【功能】批量修改bug和功能
parent
f7ec1badf7
commit
aa571f25f9
|
@ -19,13 +19,9 @@
|
||||||
<view class="ss-flex ss-flex-wrap ss-p-x-20 ss-m-t-20 ss-col-top">
|
<view class="ss-flex ss-flex-wrap ss-p-x-20 ss-m-t-20 ss-col-top">
|
||||||
<view class="goods-list-box">
|
<view class="goods-list-box">
|
||||||
<view class="left-list" v-for="item in state.leftGoodsList" :key="item.id">
|
<view class="left-list" v-for="item in state.leftGoodsList" :key="item.id">
|
||||||
<s-goods-column
|
<s-goods-column class="goods-md-box" size="md" :data="item"
|
||||||
class="goods-md-box"
|
@click="sheep.$router.go('/pages/goods/index', { id: item.id })"
|
||||||
size="md"
|
@getHeight="mountMasonry($event, 'left')">
|
||||||
:data="item"
|
|
||||||
@click="sheep.$router.go('/pages/goods/index', { id: item.id })"
|
|
||||||
@getHeight="mountMasonry($event, 'left')"
|
|
||||||
>
|
|
||||||
<template v-slot:cart>
|
<template v-slot:cart>
|
||||||
<button class="ss-reset-button cart-btn"> </button>
|
<button class="ss-reset-button cart-btn"> </button>
|
||||||
</template>
|
</template>
|
||||||
|
@ -34,13 +30,9 @@
|
||||||
</view>
|
</view>
|
||||||
<view class="goods-list-box">
|
<view class="goods-list-box">
|
||||||
<view class="right-list" v-for="item in state.rightGoodsList" :key="item.id">
|
<view class="right-list" v-for="item in state.rightGoodsList" :key="item.id">
|
||||||
<s-goods-column
|
<s-goods-column class="goods-md-box" size="md" :data="item"
|
||||||
class="goods-md-box"
|
@click="sheep.$router.go('/pages/goods/index', { id: item.id })"
|
||||||
size="md"
|
@getHeight="mountMasonry($event, 'right')">
|
||||||
:data="item"
|
|
||||||
@click="sheep.$router.go('/pages/goods/index', { id: item.id })"
|
|
||||||
@getHeight="mountMasonry($event, 'right')"
|
|
||||||
>
|
|
||||||
<template v-slot:cart>
|
<template v-slot:cart>
|
||||||
<button class="ss-reset-button cart-btn" />
|
<button class="ss-reset-button cart-btn" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -49,23 +41,27 @@
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<uni-load-more
|
<uni-load-more v-if="state.pagination.total > 0" :status="state.loadStatus" :content-text="{
|
||||||
v-if="state.pagination.total > 0"
|
|
||||||
:status="state.loadStatus"
|
|
||||||
:content-text="{
|
|
||||||
contentdown: '上拉加载更多',
|
contentdown: '上拉加载更多',
|
||||||
}"
|
}" @tap="loadMore" />
|
||||||
@tap="loadMore"
|
|
||||||
/>
|
|
||||||
</s-layout>
|
</s-layout>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive } from 'vue';
|
import {
|
||||||
import { onLoad, onReachBottom } from '@dcloudio/uni-app';
|
reactive,
|
||||||
|
toRaw,
|
||||||
|
ref
|
||||||
|
} from 'vue';
|
||||||
|
import {
|
||||||
|
onLoad,
|
||||||
|
onReachBottom
|
||||||
|
} from '@dcloudio/uni-app';
|
||||||
import sheep from '@/sheep';
|
import sheep from '@/sheep';
|
||||||
import _ from 'lodash-es';
|
import _ from 'lodash-es';
|
||||||
import RewardActivityApi from '@/sheep/api/promotion/rewardActivity';
|
import RewardActivityApi from '@/sheep/api/promotion/rewardActivity';
|
||||||
import { formatRewardActivityRule } from '@/sheep/hooks/useGoods';
|
import {
|
||||||
|
formatRewardActivityRule
|
||||||
|
} from '@/sheep/hooks/useGoods';
|
||||||
import SpuApi from '@/sheep/api/product/spu';
|
import SpuApi from '@/sheep/api/product/spu';
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
|
@ -106,32 +102,138 @@
|
||||||
|
|
||||||
// 加载商品信息
|
// 加载商品信息
|
||||||
async function getList() {
|
async function getList() {
|
||||||
|
// state.loadStatus = 'loading';
|
||||||
// 处理拓展参数
|
// 处理拓展参数
|
||||||
const params = {};
|
const params = {}
|
||||||
if (state.activityInfo.productScope === 2) {
|
if (state.activityInfo.productScope === 2) {
|
||||||
params.ids = state.activityInfo.productSpuIds.join(',');
|
// const params = toRaw(state.activityInfo.productScopeValues)
|
||||||
|
// 请求数据
|
||||||
|
const {
|
||||||
|
code,
|
||||||
|
data
|
||||||
|
} = await SpuApi.getSpuListByIds(state.activityInfo.productScopeValues.join(','));
|
||||||
|
if (code !== 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 使用 map 提取每个对象的 id 属性
|
||||||
|
const ids = data.map(item => item.id);
|
||||||
|
// 使用 join 方法将 id 数组连接成一个用逗号分隔的字符串
|
||||||
|
const idsString = ids.join(',');
|
||||||
|
// 获取结算信息
|
||||||
|
settleData.value = await getSettlementByIds(idsString)
|
||||||
|
// 处理获得的数据
|
||||||
|
const ms = enrichDataWithSkus(data, settleData.value)
|
||||||
|
state.pagination.list = ms;
|
||||||
|
// state.pagination.total = data.total;
|
||||||
|
// state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
|
||||||
} else if (state.activityInfo.productScope === 3) {
|
} else if (state.activityInfo.productScope === 3) {
|
||||||
params.categoryIds = state.activityInfo.productSpuIds.join(',');
|
params.categoryIds = state.activityInfo.productScopeValues.join(',');
|
||||||
|
state.loadStatus = 'loading';
|
||||||
|
const {
|
||||||
|
code,
|
||||||
|
data
|
||||||
|
} = await SpuApi.getSpuPage({
|
||||||
|
pageNo: state.pagination.pageNo,
|
||||||
|
pageSize: state.pagination.pageSize,
|
||||||
|
...params,
|
||||||
|
});
|
||||||
|
if (code !== 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 使用 map 提取每个对象的 id 属性
|
||||||
|
const ids = data.list.map(item => item.id);
|
||||||
|
// 使用 join 方法将 id 数组连接成一个用逗号分隔的字符串
|
||||||
|
const idsString = ids.join(',');
|
||||||
|
// 获取结算信息
|
||||||
|
settleData.value = await getSettlementByIds(idsString)
|
||||||
|
// 处理获得的数据
|
||||||
|
const ms = enrichDataWithSkus(data.list, settleData.value)
|
||||||
|
state.pagination.list = _.concat(state.pagination.list, ms);
|
||||||
|
state.pagination.total = data.total;
|
||||||
|
state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
|
||||||
|
} else {
|
||||||
|
state.loadStatus = 'loading';
|
||||||
|
const {
|
||||||
|
code,
|
||||||
|
data
|
||||||
|
} = await SpuApi.getSpuPage({
|
||||||
|
pageNo: state.pagination.pageNo,
|
||||||
|
pageSize: state.pagination.pageSize,
|
||||||
|
});
|
||||||
|
if (code !== 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 使用 map 提取每个对象的 id 属性
|
||||||
|
const ids = data.list.map(item => item.id);
|
||||||
|
// 使用 join 方法将 id 数组连接成一个用逗号分隔的字符串
|
||||||
|
const idsString = ids.join(',');
|
||||||
|
// 获取结算信息
|
||||||
|
settleData.value = await getSettlementByIds(idsString)
|
||||||
|
// 处理获得的数据
|
||||||
|
const ms = enrichDataWithSkus(data.list, settleData.value)
|
||||||
|
state.pagination.list = _.concat(state.pagination.list, ms);
|
||||||
|
state.pagination.total = data.total;
|
||||||
|
state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
|
||||||
}
|
}
|
||||||
// 请求数据
|
|
||||||
state.loadStatus = 'loading';
|
|
||||||
const { code, data } = await SpuApi.getSpuPage({
|
|
||||||
pageNo: state.pagination.pageNo,
|
|
||||||
pageSize: state.pagination.pageSize,
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
if (code !== 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
state.pagination.list = _.concat(state.pagination.list, data.list);
|
|
||||||
state.pagination.total = data.total;
|
|
||||||
state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
|
|
||||||
mountMasonry();
|
mountMasonry();
|
||||||
}
|
}
|
||||||
|
//获取结算信息
|
||||||
|
const settleData = ref()
|
||||||
|
async function getSettlementByIds(ids) {
|
||||||
|
const {
|
||||||
|
data
|
||||||
|
} = await SpuApi.getSettlementProduct(ids);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
//计算展示价格的函数
|
||||||
|
function enrichDataWithSkus(data, array) {
|
||||||
|
// 创建一个映射,以 id 为键,存储 data 数组中的对象
|
||||||
|
const dataMap = new Map(data.map(item => [item.id, {
|
||||||
|
...item
|
||||||
|
}]));
|
||||||
|
|
||||||
|
// 遍历 array 数组
|
||||||
|
array.forEach(item => {
|
||||||
|
// 初始化 discountPrice 和 vipPrice 为 null
|
||||||
|
let discountPrice = null;
|
||||||
|
let vipPrice = null;
|
||||||
|
let foundType4 = false;
|
||||||
|
let foundType6 = false;
|
||||||
|
|
||||||
|
// 遍历 skus 数组,寻找 type 为 4 和 6 的首个条目
|
||||||
|
item.skus.forEach(sku => {
|
||||||
|
if (!foundType4 && sku.type === 4) {
|
||||||
|
discountPrice = sku.price;
|
||||||
|
foundType4 = true;
|
||||||
|
}
|
||||||
|
if (!foundType6 && sku.type === 6) {
|
||||||
|
vipPrice = sku.price;
|
||||||
|
foundType6 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果已经找到 type 为 4 和 6 的条目,则不需要继续遍历
|
||||||
|
if (foundType4 && foundType6) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新 dataMap 中对应的对象
|
||||||
|
if (dataMap.has(item.id)) {
|
||||||
|
dataMap.get(item.id).discountPrice = discountPrice;
|
||||||
|
dataMap.get(item.id).vipPrice = vipPrice;
|
||||||
|
dataMap.get(item.id).reward = item.reward;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 返回更新后的数据数组
|
||||||
|
return Array.from(dataMap.values());
|
||||||
|
}
|
||||||
// 加载活动信息
|
// 加载活动信息
|
||||||
async function getActivity(id) {
|
async function getActivity(id) {
|
||||||
const { code, data } = await RewardActivityApi.getRewardActivity(id);
|
const {
|
||||||
|
code,
|
||||||
|
data
|
||||||
|
} = await RewardActivityApi.getRewardActivity(id);
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
state.activityInfo = data;
|
state.activityInfo = data;
|
||||||
}
|
}
|
||||||
|
@ -154,28 +256,32 @@
|
||||||
onLoad(async (options) => {
|
onLoad(async (options) => {
|
||||||
state.activityId = options.activityId;
|
state.activityId = options.activityId;
|
||||||
await getActivity(state.activityId);
|
await getActivity(state.activityId);
|
||||||
await getList(state.activityId);
|
await getList();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.goods-list-box {
|
.goods-list-box {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
.left-list {
|
.left-list {
|
||||||
margin-right: 10rpx;
|
margin-right: 10rpx;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.right-list {
|
.right-list {
|
||||||
margin-left: 10rpx;
|
margin-left: 10rpx;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tip-box {
|
.tip-box {
|
||||||
background: #fff0e7;
|
background: #fff0e7;
|
||||||
padding: 20rpx;
|
padding: 20rpx;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
.activity-left-image {
|
.activity-left-image {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
@ -183,6 +289,7 @@
|
||||||
width: 58rpx;
|
width: 58rpx;
|
||||||
height: 36rpx;
|
height: 36rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.activity-right-image {
|
.activity-right-image {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
@ -190,12 +297,14 @@
|
||||||
width: 72rpx;
|
width: 72rpx;
|
||||||
height: 50rpx;
|
height: 50rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.type-text {
|
.type-text {
|
||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #ff6000;
|
color: #ff6000;
|
||||||
line-height: 42rpx;
|
line-height: 42rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tip-content {
|
.tip-content {
|
||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
@ -203,4 +312,4 @@
|
||||||
line-height: 42rpx;
|
line-height: 42rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
|
@ -2,10 +2,7 @@
|
||||||
<template>
|
<template>
|
||||||
<s-layout navbar="inner" :bgStyle="{ color: 'rgb(245,28,19)' }">
|
<s-layout navbar="inner" :bgStyle="{ color: 'rgb(245,28,19)' }">
|
||||||
<!--顶部背景图-->
|
<!--顶部背景图-->
|
||||||
<view
|
<view class="page-bg" :style="[{ marginTop: '-' + Number(statusBarHeight + 88) + 'rpx' }]"></view>
|
||||||
class="page-bg"
|
|
||||||
:style="[{ marginTop: '-' + Number(statusBarHeight + 88) + 'rpx' }]"
|
|
||||||
></view>
|
|
||||||
<!-- 时间段轮播图 -->
|
<!-- 时间段轮播图 -->
|
||||||
<view class="header" v-if="activeTimeConfig?.sliderPicUrls?.length > 0">
|
<view class="header" v-if="activeTimeConfig?.sliderPicUrls?.length > 0">
|
||||||
<swiper indicator-dots="true" autoplay="true" :circular="true" interval="3000" duration="1500"
|
<swiper indicator-dots="true" autoplay="true" :circular="true" interval="3000" duration="1500"
|
||||||
|
@ -26,13 +23,12 @@
|
||||||
</view>
|
</view>
|
||||||
<scroll-view class="time-list" :scroll-into-view="activeTimeElId" scroll-x scroll-with-animation>
|
<scroll-view class="time-list" :scroll-into-view="activeTimeElId" scroll-x scroll-with-animation>
|
||||||
<view v-for="(config, index) in timeConfigList" :key="index"
|
<view v-for="(config, index) in timeConfigList" :key="index"
|
||||||
:class="['item', { active: activeTimeIndex === index}]"
|
:class="['item', { active: activeTimeIndex === index}]" :id="`timeItem${index}`"
|
||||||
:id="`timeItem${index}`"
|
@tap="handleChangeTimeConfig(index,config.id)">
|
||||||
@tap="handleChangeTimeConfig(index)">
|
|
||||||
<!-- 活动起始时间 -->
|
<!-- 活动起始时间 -->
|
||||||
<view class="time">{{ config.startTime }}</view>
|
<view class="time">{{ config.startTime }}</view>
|
||||||
<!-- 活动状态 -->
|
<!-- 活动状态 -->
|
||||||
<view class="status">{{ config.status }}</view>
|
<view class="status">{{ config?.status }}</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
|
@ -57,69 +53,89 @@
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 活动列表 -->
|
<!-- 活动列表 -->
|
||||||
<scroll-view
|
<scroll-view class="scroll-box" :style="{ height: pageHeight + 'rpx' }" scroll-y="true"
|
||||||
class="scroll-box"
|
:scroll-with-animation="false" :enable-back-to-top="true">
|
||||||
:style="{ height: pageHeight + 'rpx' }"
|
|
||||||
scroll-y="true"
|
|
||||||
:scroll-with-animation="false"
|
|
||||||
:enable-back-to-top="true"
|
|
||||||
>
|
|
||||||
<view class="goods-box ss-m-b-20" v-for="activity in activityList" :key="activity.id">
|
<view class="goods-box ss-m-b-20" v-for="activity in activityList" :key="activity.id">
|
||||||
<s-goods-column
|
<s-goods-column size="lg" :data="{ ...activity, price: activity.seckillPrice }"
|
||||||
size="lg"
|
:goodsFields="goodsFields" :seckillTag="true">
|
||||||
:data="{ ...activity, price: activity.seckillPrice }"
|
|
||||||
:goodsFields="goodsFields"
|
|
||||||
:seckillTag="true"
|
|
||||||
@click="sheep.$router.go('/pages/goods/seckill', { id: activity.id })"
|
|
||||||
>
|
|
||||||
<!-- 抢购进度 -->
|
<!-- 抢购进度 -->
|
||||||
<template #activity>
|
<template #activity>
|
||||||
<view class="limit">限量 <text class="ss-m-l-5">{{ activity.stock}} {{activity.unitName}}</text></view>
|
<view class="limit">限量 <text class="ss-m-l-5">{{ activity.stock}}
|
||||||
|
{{activity.unitName}}</text></view>
|
||||||
<su-progress :percentage="activity.percent" strokeWidth="10" textInside isAnimate />
|
<su-progress :percentage="activity.percent" strokeWidth="10" textInside isAnimate />
|
||||||
</template>
|
</template>
|
||||||
<!-- 抢购按钮 -->
|
<!-- 抢购按钮 -->
|
||||||
<template #cart>
|
<template #cart>
|
||||||
<button :class="['ss-reset-button cart-btn', { disabled: activeTimeConfig.status === TimeStatusEnum.END }]">
|
<button
|
||||||
<span v-if="activeTimeConfig?.status === TimeStatusEnum.WAIT_START">未开始</span>
|
:class="['ss-reset-button cart-btn', { disabled: activeTimeConfig?.status === TimeStatusEnum.END}]"
|
||||||
<span v-else-if="activeTimeConfig?.status === TimeStatusEnum.STARTED">马上抢</span>
|
v-if="activeTimeConfig?.status === TimeStatusEnum.WAIT_START">
|
||||||
<span v-else>已结束</span>
|
<span>未开始</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
:class="['ss-reset-button cart-btn', { disabled: activeTimeConfig?.status === TimeStatusEnum.END}]"
|
||||||
|
@click="sheep.$router.go('/pages/goods/seckill', { id: activity.id })"
|
||||||
|
v-else-if='activeTimeConfig?.status === TimeStatusEnum.STARTED'>
|
||||||
|
<span>马上抢</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
:class="['ss-reset-button cart-btn', { disabled: activeTimeConfig?.status === TimeStatusEnum.END}]"
|
||||||
|
v-else>
|
||||||
|
<span>已结束</span>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</s-goods-column>
|
</s-goods-column>
|
||||||
</view>
|
</view>
|
||||||
<uni-load-more
|
<uni-load-more v-if="activityTotal > 0" :status="loadStatus" :content-text="{
|
||||||
v-if="activityTotal > 0"
|
|
||||||
:status="loadStatus"
|
|
||||||
:content-text="{
|
|
||||||
contentdown: '上拉加载更多',
|
contentdown: '上拉加载更多',
|
||||||
}"
|
}" @tap="loadMore" />
|
||||||
@tap="loadMore"
|
|
||||||
/>
|
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
</s-layout>
|
</s-layout>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import {reactive, computed, ref, nextTick} from 'vue';
|
import {
|
||||||
import { onLoad, onReachBottom } from '@dcloudio/uni-app';
|
reactive,
|
||||||
|
computed,
|
||||||
|
ref,
|
||||||
|
nextTick
|
||||||
|
} from 'vue';
|
||||||
|
import {
|
||||||
|
onLoad,
|
||||||
|
onReachBottom
|
||||||
|
} from '@dcloudio/uni-app';
|
||||||
import sheep from '@/sheep';
|
import sheep from '@/sheep';
|
||||||
import { useDurationTime } from '@/sheep/hooks/useGoods';
|
import {
|
||||||
|
useDurationTime
|
||||||
|
} from '@/sheep/hooks/useGoods';
|
||||||
import SeckillApi from "@/sheep/api/promotion/seckill";
|
import SeckillApi from "@/sheep/api/promotion/seckill";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import {TimeStatusEnum} from "@/sheep/util/const";
|
import {
|
||||||
|
TimeStatusEnum
|
||||||
|
} from "@/sheep/util/const";
|
||||||
|
|
||||||
// 计算页面高度
|
// 计算页面高度
|
||||||
const { safeAreaInsets, safeArea } = sheep.$platform.device;
|
const {
|
||||||
|
safeAreaInsets,
|
||||||
|
safeArea
|
||||||
|
} = sheep.$platform.device;
|
||||||
const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
|
const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
|
||||||
const pageHeight = (safeArea.height + safeAreaInsets.bottom) * 2 + statusBarHeight - sheep.$platform.navbar - 350;
|
const pageHeight = (safeArea.height + safeAreaInsets.bottom) * 2 + statusBarHeight - sheep.$platform.navbar - 350;
|
||||||
const headerBg = sheep.$url.css('/static/img/shop/goods/seckill-header.png');
|
const headerBg = sheep.$url.css('/static/img/shop/goods/seckill-header.png');
|
||||||
|
|
||||||
// 商品控件显示的字段(不显示库存、销量。改为显示自定义的进度条)
|
// 商品控件显示的字段(不显示库存、销量。改为显示自定义的进度条)
|
||||||
const goodsFields = {
|
const goodsFields = {
|
||||||
name: { show: true },
|
name: {
|
||||||
introduction: { show: true },
|
show: true
|
||||||
price: { show: true },
|
},
|
||||||
marketPrice: { show: true },
|
introduction: {
|
||||||
|
show: true
|
||||||
|
},
|
||||||
|
price: {
|
||||||
|
show: true
|
||||||
|
},
|
||||||
|
marketPrice: {
|
||||||
|
show: true
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
//#region 时间段
|
//#region 时间段
|
||||||
|
@ -127,25 +143,32 @@
|
||||||
const timeConfigList = ref([])
|
const timeConfigList = ref([])
|
||||||
// 查询时间段
|
// 查询时间段
|
||||||
const getSeckillConfigList = async () => {
|
const getSeckillConfigList = async () => {
|
||||||
const { data } = await SeckillApi.getSeckillConfigList()
|
const {
|
||||||
|
data
|
||||||
|
} = await SeckillApi.getSeckillConfigList()
|
||||||
const now = dayjs();
|
const now = dayjs();
|
||||||
const today = now.format('YYYY-MM-DD')
|
const today = now.format('YYYY-MM-DD')
|
||||||
|
const select = ref([])
|
||||||
// 判断时间段的状态
|
// 判断时间段的状态
|
||||||
data.forEach((config, index) => {
|
data.forEach((config, index) => {
|
||||||
const startTime = dayjs(`${today} ${config.startTime}`)
|
const startTime = dayjs(`${today} ${config.startTime}`)
|
||||||
const endTime = dayjs(`${today} ${config.endTime}`)
|
const endTime = dayjs(`${today} ${config.endTime}`)
|
||||||
|
select.value[index] = config.id;
|
||||||
if (now.isBefore(startTime)) {
|
if (now.isBefore(startTime)) {
|
||||||
config.status = TimeStatusEnum.WAIT_START;
|
config.status = TimeStatusEnum.WAIT_START;
|
||||||
|
// select.value[index] = config.id;
|
||||||
} else if (now.isAfter(endTime)) {
|
} else if (now.isAfter(endTime)) {
|
||||||
config.status = TimeStatusEnum.END;
|
config.status = TimeStatusEnum.END;
|
||||||
|
// select.value[index] = config.id;
|
||||||
} else {
|
} else {
|
||||||
config.status = TimeStatusEnum.STARTED;
|
config.status = TimeStatusEnum.STARTED;
|
||||||
activeTimeIndex.value = index;
|
// select.value[index] = config.id;
|
||||||
|
activeTimeIndex.value = index
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
timeConfigList.value = data
|
timeConfigList.value = data
|
||||||
// 默认选中进行中的活动
|
// 默认选中进行中的活动
|
||||||
handleChangeTimeConfig(activeTimeIndex.value);
|
handleChangeTimeConfig(activeTimeIndex.value, select.value[activeTimeIndex.value]);
|
||||||
// 滚动到进行中的时间段
|
// 滚动到进行中的时间段
|
||||||
scrollToTimeConfig(activeTimeIndex.value)
|
scrollToTimeConfig(activeTimeIndex.value)
|
||||||
}
|
}
|
||||||
|
@ -159,11 +182,12 @@
|
||||||
// 切换时间段
|
// 切换时间段
|
||||||
const activeTimeIndex = ref(0) // 当前选中的时间段的索引
|
const activeTimeIndex = ref(0) // 当前选中的时间段的索引
|
||||||
const activeTimeConfig = computed(() => timeConfigList.value[activeTimeIndex.value]) // 当前选中的时间段
|
const activeTimeConfig = computed(() => timeConfigList.value[activeTimeIndex.value]) // 当前选中的时间段
|
||||||
const handleChangeTimeConfig = (index) => {
|
const handleChangeTimeConfig = (index, id) => {
|
||||||
activeTimeIndex.value = index
|
activeTimeIndex.value = index
|
||||||
|
|
||||||
// 查询活动列表
|
// 查询活动列表
|
||||||
activityPageParams.pageNo = 1
|
activityPageParams.pageNo = 1
|
||||||
|
activityPageParams.configId = id;
|
||||||
activityList.value = []
|
activityList.value = []
|
||||||
getActivityList();
|
getActivityList();
|
||||||
}
|
}
|
||||||
|
@ -182,7 +206,7 @@
|
||||||
|
|
||||||
// 查询活动列表
|
// 查询活动列表
|
||||||
const activityPageParams = reactive({
|
const activityPageParams = reactive({
|
||||||
id: 0, // 时间段 ID
|
configId: 0, // 时间段 ID
|
||||||
pageNo: 1, // 页码
|
pageNo: 1, // 页码
|
||||||
pageSize: 5, // 每页数量
|
pageSize: 5, // 每页数量
|
||||||
})
|
})
|
||||||
|
@ -191,7 +215,9 @@
|
||||||
const loadStatus = ref('') // 页面加载状态
|
const loadStatus = ref('') // 页面加载状态
|
||||||
async function getActivityList() {
|
async function getActivityList() {
|
||||||
loadStatus.value = 'loading';
|
loadStatus.value = 'loading';
|
||||||
const { data } = await SeckillApi.getSeckillActivityPage(activityPageParams)
|
const {
|
||||||
|
data
|
||||||
|
} = await SeckillApi.getSeckillActivityPage(activityPageParams)
|
||||||
data.list.forEach(activity => {
|
data.list.forEach(activity => {
|
||||||
// 计算抢购进度
|
// 计算抢购进度
|
||||||
activity.percent = parseInt(100 * (activity.totalStock - activity.stock) / activity.totalStock);
|
activity.percent = parseInt(100 * (activity.totalStock - activity.stock) / activity.totalStock);
|
||||||
|
@ -235,7 +261,8 @@
|
||||||
margin: -276rpx auto 0 auto;
|
margin: -276rpx auto 0 auto;
|
||||||
border-radius: 14rpx;
|
border-radius: 14rpx;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
swiper{
|
|
||||||
|
swiper {
|
||||||
height: 330rpx !important;
|
height: 330rpx !important;
|
||||||
border-radius: 14rpx;
|
border-radius: 14rpx;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -246,7 +273,8 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border-radius: 14rpx;
|
border-radius: 14rpx;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
img{
|
|
||||||
|
img {
|
||||||
border-radius: 14rpx;
|
border-radius: 14rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,10 +285,12 @@
|
||||||
width: 75rpx;
|
width: 75rpx;
|
||||||
height: 70rpx;
|
height: 70rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 时间段列表
|
// 时间段列表
|
||||||
.time-list {
|
.time-list {
|
||||||
width: 596rpx;
|
width: 596rpx;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
// 时间段
|
// 时间段
|
||||||
.item {
|
.item {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -270,17 +300,20 @@
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin-right: 30rpx;
|
margin-right: 30rpx;
|
||||||
width: 130rpx;
|
width: 130rpx;
|
||||||
|
|
||||||
// 开始时间
|
// 开始时间
|
||||||
.time {
|
.time {
|
||||||
font-size: 36rpx;
|
font-size: 36rpx;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选中的时间段
|
// 选中的时间段
|
||||||
&.active {
|
&.active {
|
||||||
.time {
|
.time {
|
||||||
color: var(--ui-BG-Main);
|
color: var(--ui-BG-Main);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 状态
|
// 状态
|
||||||
.status {
|
.status {
|
||||||
height: 30rpx;
|
height: 30rpx;
|
||||||
|
@ -301,6 +334,7 @@
|
||||||
margin: 0 20rpx 0 20rpx;
|
margin: 0 20rpx 0 20rpx;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: 20rpx 20rpx 0 0;
|
border-radius: 20rpx 20rpx 0 0;
|
||||||
|
|
||||||
.content-header {
|
.content-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-radius: 20rpx 20rpx 0 0;
|
border-radius: 20rpx 20rpx 0 0;
|
||||||
|
@ -312,6 +346,7 @@
|
||||||
height: 64rpx;
|
height: 64rpx;
|
||||||
background: rgba($color: #fff, $alpha: 0.66);
|
background: rgba($color: #fff, $alpha: 0.66);
|
||||||
border-radius: 32px;
|
border-radius: 32px;
|
||||||
|
|
||||||
// 场次倒计时内容
|
// 场次倒计时内容
|
||||||
.countdown-title {
|
.countdown-title {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
|
@ -319,10 +354,12 @@
|
||||||
color: #333333;
|
color: #333333;
|
||||||
line-height: 28rpx;
|
line-height: 28rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 场次倒计时
|
// 场次倒计时
|
||||||
.countdown-time {
|
.countdown-time {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
color: rgba(#ed3c30, 0.23);
|
color: rgba(#ed3c30, 0.23);
|
||||||
|
|
||||||
// 场次倒计时:小时部分
|
// 场次倒计时:小时部分
|
||||||
.countdown-h {
|
.countdown-h {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
|
@ -334,6 +371,7 @@
|
||||||
background: rgba(#ed3c30, 0.23);
|
background: rgba(#ed3c30, 0.23);
|
||||||
border-radius: 6rpx;
|
border-radius: 6rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 场次倒计时:分钟、秒
|
// 场次倒计时:分钟、秒
|
||||||
.countdown-num {
|
.countdown-num {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
|
@ -348,12 +386,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 活动列表
|
// 活动列表
|
||||||
.scroll-box {
|
.scroll-box {
|
||||||
height: 900rpx;
|
height: 900rpx;
|
||||||
|
|
||||||
// 活动
|
// 活动
|
||||||
.goods-box {
|
.goods-box {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
// 抢购按钮
|
// 抢购按钮
|
||||||
.cart-btn {
|
.cart-btn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -373,6 +414,7 @@
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 秒杀限量商品数
|
// 秒杀限量商品数
|
||||||
.limit {
|
.limit {
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
|
@ -382,4 +424,4 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
|
@ -36,10 +36,10 @@
|
||||||
<text v-else>
|
<text v-else>
|
||||||
{{
|
{{
|
||||||
state.coupon.status === 1
|
state.coupon.status === 1
|
||||||
? '立即使用'
|
? '可使用'
|
||||||
: state.coupon.status === 2
|
: state.coupon.status === 2
|
||||||
? '已使用'
|
? '已使用'
|
||||||
: '已过期'
|
: '已过期'
|
||||||
}}
|
}}
|
||||||
</text>
|
</text>
|
||||||
</button>
|
</button>
|
||||||
|
@ -282,11 +282,11 @@
|
||||||
|
|
||||||
.detail-wrap {
|
.detail-wrap {
|
||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
180deg,
|
180deg,
|
||||||
var(--ui-BG-Main),
|
var(--ui-BG-Main),
|
||||||
var(--ui-BG-Main-gradient),
|
var(--ui-BG-Main-gradient),
|
||||||
var(--ui-BG-Main),
|
var(--ui-BG-Main),
|
||||||
#fff
|
#fff
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,30 +7,47 @@
|
||||||
<!-- 骨架屏 -->
|
<!-- 骨架屏 -->
|
||||||
<detailSkeleton v-if="state.skeletonLoading" />
|
<detailSkeleton v-if="state.skeletonLoading" />
|
||||||
<!-- 下架/售罄提醒 -->
|
<!-- 下架/售罄提醒 -->
|
||||||
<s-empty
|
<s-empty v-else-if="state.goodsInfo === null" text="商品不存在或已下架" icon="/static/soldout-empty.png" showAction
|
||||||
v-else-if="state.goodsInfo === null"
|
actionText="再逛逛" actionUrl="/pages/goods/list" />
|
||||||
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
|
<su-swiper class="ss-m-b-14" isPreview :list="formatGoodsSwiper(state.goodsInfo.sliderPicUrls)"
|
||||||
class="ss-m-b-14"
|
otStyle="tag" imageMode="widthFix" dotCur="bg-mask-40" :seizeHeight="750" />
|
||||||
isPreview
|
<!-- 限时折扣 -->
|
||||||
:list="formatGoodsSwiper(state.goodsInfo.sliderPicUrls)"
|
<view class="discount" v-if="setShow">
|
||||||
otStyle="tag"
|
<image class="disImg" src="../../static/images/dis.png"></image>
|
||||||
imageMode="widthFix"
|
<view class="discountCont">
|
||||||
dotCur="bg-mask-40"
|
<view class="disContT">
|
||||||
:seizeHeight="750"
|
<view class="disContT1">
|
||||||
/>
|
<view class="disContT1P">
|
||||||
|
¥{{fen2yuan(settleData.price)}}
|
||||||
|
</view>
|
||||||
|
<view class="disContT1End">
|
||||||
|
直降¥{{fen2yuan( state.goodsInfo.price - settleData.price)}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="disContT2">
|
||||||
|
限时折扣
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="disContB">
|
||||||
|
<view class="disContB1">
|
||||||
|
价格:¥{{fen2yuan(state.goodsInfo.price)}} 丨 剩余:{{settleData.stock}}
|
||||||
|
</view>
|
||||||
|
<view class="disContB2">
|
||||||
|
距结束仅剩
|
||||||
|
<countDown :tipText="' '" :bgColor="bgColor" :dayText="':'" :hourText="':'"
|
||||||
|
:minuteText="':'" :secondText="' '" :datatime="settleData.endTime / 1000"
|
||||||
|
:isDay="false" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 限时折扣 -->
|
||||||
<!-- 价格+标题 -->
|
<!-- 价格+标题 -->
|
||||||
<view class="title-card detail-card ss-p-y-40 ss-p-x-20">
|
<view class="title-card detail-card ss-p-y-40 ss-p-x-20">
|
||||||
<view class="ss-flex ss-row-between ss-col-center ss-m-b-26">
|
<view class="ss-flex ss-row-between ss-col-center ss-m-b-26" v-if="!setShow">
|
||||||
<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) }}
|
||||||
|
@ -47,23 +64,16 @@
|
||||||
<!-- 满减送/限时折扣活动的提示 -->
|
<!-- 满减送/限时折扣活动的提示 -->
|
||||||
<div class="tag-content">
|
<div class="tag-content">
|
||||||
<view class="tag-box ss-flex">
|
<view class="tag-box ss-flex">
|
||||||
<view
|
<view class="tag ss-m-r-10" v-for="promos in state.activityInfo" :key="promos.id"
|
||||||
class="tag ss-m-r-10"
|
@tap="onActivity">
|
||||||
v-for="promos in state.activityInfo"
|
|
||||||
:key="promos.id"
|
|
||||||
@tap="onActivity"
|
|
||||||
>
|
|
||||||
{{ promos.name }}
|
{{ promos.name }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 优惠劵 -->
|
<!-- 优惠劵@tap="state.showModel = true" -->
|
||||||
<view
|
<view class="get-coupon-box ss-flex ss-col-center ss-m-l-20" @tap="onActivity"
|
||||||
class="get-coupon-box ss-flex ss-col-center ss-m-l-20"
|
v-if="state.couponInfo.length">
|
||||||
@tap="state.showModel = true"
|
|
||||||
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>
|
||||||
|
@ -74,51 +84,30 @@
|
||||||
|
|
||||||
<!-- 功能卡片 -->
|
<!-- 功能卡片 -->
|
||||||
<view class="detail-cell-card detail-card ss-flex-col">
|
<view class="detail-cell-card detail-card ss-flex-col">
|
||||||
<detail-cell-sku
|
<detail-cell-sku v-model="state.selectedSku.goods_sku_text" :sku="state.selectedSku"
|
||||||
v-model="state.selectedSku.goods_sku_text"
|
@tap="state.showSelectSku = true" />
|
||||||
:sku="state.selectedSku"
|
|
||||||
@tap="state.showSelectSku = true"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 规格与数量弹框 -->
|
<!-- 规格与数量弹框 -->
|
||||||
<s-select-sku
|
<s-select-sku :goodsInfo="state.goodsInfo" :show="state.showSelectSku" @addCart="onAddCart"
|
||||||
:goodsInfo="state.goodsInfo"
|
@buy="onBuy" @change="onSkuChange" @close="state.showSelectSku = false" />
|
||||||
: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
|
<detail-content-card class="detail-content-selector" :content="state.goodsInfo.description" />
|
||||||
class="detail-content-selector"
|
|
||||||
:content="state.goodsInfo.description"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 活动跳转:拼团/秒杀/砍价活动 -->
|
<!-- 活动跳转:拼团/秒杀/砍价活动 -->
|
||||||
<detail-activity-tip
|
<detail-activity-tip v-if="state.activityList.length > 0" :activity-list="state.activityList" />
|
||||||
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
|
<button class="ss-reset-button add-btn ui-Shadow-Main" @tap="state.showSelectSku = true">
|
||||||
class="ss-reset-button add-btn ui-Shadow-Main"
|
|
||||||
@tap="state.showSelectSku = true"
|
|
||||||
>
|
|
||||||
加入购物车
|
加入购物车
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button class="ss-reset-button buy-btn ui-Shadow-Main" @tap="state.showSelectSku = true">
|
||||||
class="ss-reset-button buy-btn ui-Shadow-Main"
|
|
||||||
@tap="state.showSelectSku = true"
|
|
||||||
>
|
|
||||||
立即购买
|
立即购买
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
|
@ -128,32 +117,38 @@
|
||||||
</detail-tabbar>
|
</detail-tabbar>
|
||||||
|
|
||||||
<!-- 优惠劵弹窗 -->
|
<!-- 优惠劵弹窗 -->
|
||||||
<s-coupon-get
|
<!-- <s-coupon-get v-model="state.couponInfo" :show="state.showModel" @close="state.showModel = false"
|
||||||
v-model="state.couponInfo"
|
@get="onGet" /> -->
|
||||||
:show="state.showModel"
|
|
||||||
@close="state.showModel = false"
|
|
||||||
@get="onGet"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 满减送/限时折扣活动弹窗 -->
|
<!-- 满减送/限时折扣活动弹窗 -->
|
||||||
<s-activity-pop
|
<s-activity-pop v-model="state" :show="state.showActivityModel"
|
||||||
v-model="state.activityInfo"
|
@close="state.showActivityModel = false" @get="onGet" />
|
||||||
:show="state.showActivityModel"
|
|
||||||
@close="state.showActivityModel = false"
|
|
||||||
/>
|
|
||||||
</block>
|
</block>
|
||||||
</s-layout>
|
</s-layout>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, computed } from 'vue';
|
import {
|
||||||
import { onLoad, onPageScroll } from '@dcloudio/uni-app';
|
reactive,
|
||||||
|
computed,
|
||||||
|
ref
|
||||||
|
} 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';
|
||||||
import FavoriteApi from '@/sheep/api/product/favorite';
|
import FavoriteApi from '@/sheep/api/product/favorite';
|
||||||
import { formatSales, formatGoodsSwiper, fen2yuan } from '@/sheep/hooks/useGoods';
|
import {
|
||||||
|
formatSales,
|
||||||
|
formatGoodsSwiper,
|
||||||
|
fen2yuan,
|
||||||
|
handList,
|
||||||
|
handListPrice
|
||||||
|
} 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';
|
||||||
import detailTabbar from './components/detail/detail-tabbar.vue';
|
import detailTabbar from './components/detail/detail-tabbar.vue';
|
||||||
|
@ -161,11 +156,22 @@
|
||||||
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 { isEmpty } from 'lodash-es';
|
import {
|
||||||
|
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'
|
||||||
|
|
||||||
|
const bgColor = {
|
||||||
|
'bgColor': '#E93323',
|
||||||
|
'Color': '#fff',
|
||||||
|
'width': '44rpx',
|
||||||
|
'timeTxtwidth': '16rpx',
|
||||||
|
'isDay': true
|
||||||
|
}
|
||||||
const isLogin = computed(() => sheep.$store('user').isLogin);
|
const isLogin = computed(() => sheep.$store('user').isLogin);
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
goodsId: 0,
|
goodsId: 0,
|
||||||
|
@ -182,7 +188,13 @@
|
||||||
|
|
||||||
// 规格变更
|
// 规格变更
|
||||||
function onSkuChange(e) {
|
function onSkuChange(e) {
|
||||||
state.selectedSku = e;
|
if (e.type == 4) {
|
||||||
|
settleData.value = e
|
||||||
|
setShow.value = true
|
||||||
|
} else {
|
||||||
|
state.selectedSku = e;
|
||||||
|
setShow.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加购物车
|
// 添加购物车
|
||||||
|
@ -196,21 +208,17 @@
|
||||||
|
|
||||||
// 立即购买
|
// 立即购买
|
||||||
function onBuy(e) {
|
function onBuy(e) {
|
||||||
if (!state.selectedSku.id) {
|
if (!e.id) {
|
||||||
sheep.$helper.toast('请选择商品规格');
|
sheep.$helper.toast('请选择商品规格');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
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
|
||||||
},
|
}]
|
||||||
],
|
|
||||||
// TODO 芋艿:后续清理掉这 2 参数
|
|
||||||
deliveryType: 1,
|
|
||||||
pointStatus: false,
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -222,7 +230,9 @@
|
||||||
|
|
||||||
// 立即领取
|
// 立即领取
|
||||||
async function onGet(id) {
|
async function onGet(id) {
|
||||||
const { code } = await CouponApi.takeCoupon(id);
|
const {
|
||||||
|
code
|
||||||
|
} = await CouponApi.takeCoupon(id);
|
||||||
if (code !== 0) {
|
if (code !== 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -237,33 +247,66 @@
|
||||||
// TODO 芋艿:待测试
|
// TODO 芋艿:待测试
|
||||||
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,
|
params: {
|
||||||
params: {
|
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 { code, data } = await CouponApi.getCouponTemplateList(state.goodsId, 2, 10);
|
const {
|
||||||
|
code,
|
||||||
|
data
|
||||||
|
} = await CouponApi.getCouponTemplateList(state.goodsId, 2, 10);
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
state.couponInfo = data;
|
state.couponInfo = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//获取结算信息
|
||||||
|
const setShow = ref(false)
|
||||||
|
const settleData = ref()
|
||||||
|
|
||||||
|
async function getSettlementByIds(ids) {
|
||||||
|
const { data } = await SpuApi.getSettlementProduct(ids);
|
||||||
|
settleData.value = handle(data)
|
||||||
|
state.goodsInfo.skus = handListPrice(state.goodsInfo.skus, data[0].skus)
|
||||||
|
}
|
||||||
|
|
||||||
|
//判断是否有限时折扣信息
|
||||||
|
function handle(array) {
|
||||||
|
let setList = {}
|
||||||
|
array.some(item => {
|
||||||
|
return item.skus.some(items => {
|
||||||
|
if (items.type === 4) {
|
||||||
|
setShow.value = true;
|
||||||
|
setList = items;
|
||||||
|
return true; // 返回true以结束some循环
|
||||||
|
}
|
||||||
|
return false; // 继续遍历
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// 将库存信息加入
|
||||||
|
state.goodsInfo.skus.forEach(item => {
|
||||||
|
if (item.id == setList.skuId) {
|
||||||
|
setList.stock = item.stock
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return setList
|
||||||
|
}
|
||||||
|
|
||||||
onLoad((options) => {
|
onLoad((options) => {
|
||||||
// 非法参数
|
// 非法参数
|
||||||
if (!options.id) {
|
if (!options.id) {
|
||||||
|
@ -281,7 +324,6 @@
|
||||||
// 加载到商品
|
// 加载到商品
|
||||||
state.skeletonLoading = false;
|
state.skeletonLoading = false;
|
||||||
state.goodsInfo = res.data;
|
state.goodsInfo = res.data;
|
||||||
|
|
||||||
// 加载是否收藏
|
// 加载是否收藏
|
||||||
if (isLogin.value) {
|
if (isLogin.value) {
|
||||||
FavoriteApi.isFavoriteExists(state.goodsId, 'goods').then((res) => {
|
FavoriteApi.isFavoriteExists(state.goodsId, 'goods').then((res) => {
|
||||||
|
@ -301,19 +343,19 @@
|
||||||
if (res.code !== 0) {
|
if (res.code !== 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
res.data.forEach((activity) => {
|
let activData = handList(res.data)
|
||||||
if ([1, 2, 3].includes(activity.type)) {
|
activData.forEach(activity => {
|
||||||
// 情况一:拼团/秒杀/砍价
|
if ([1, 2, 3].includes(activity.type)) { // 情况一:拼团/秒杀/砍价
|
||||||
state.activityList.push(activity);
|
state.activityList.push(activity);
|
||||||
} else if (activity.type === 5) {
|
} else if (activity.type === 5) { // 情况二:满减送
|
||||||
// 情况二:满减送
|
|
||||||
state.activityInfo.push(activity);
|
state.activityInfo.push(activity);
|
||||||
} else {
|
} else { // 情况三:限时折扣 TODO 芋艿
|
||||||
// 情况三:限时折扣 TODO 芋艿
|
// console.log('待实现!优先级不高');
|
||||||
console.log('待实现!优先级不高');
|
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
});
|
});
|
||||||
|
//获取结算信息
|
||||||
|
getSettlementByIds(state.goodsId)
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -462,4 +504,101 @@
|
||||||
color: #333333;
|
color: #333333;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
// 限时折扣
|
||||||
|
.discount {
|
||||||
|
width: 750rpx;
|
||||||
|
height: 100rpx;
|
||||||
|
// background-color: red;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disImg {
|
||||||
|
width: 750rpx;
|
||||||
|
height: 100rpx;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.discountCont {
|
||||||
|
width: 680rpx;
|
||||||
|
height: 90rpx;
|
||||||
|
margin: 10rpx auto 0 auto;
|
||||||
|
// background-color: gold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disContT {
|
||||||
|
width: 680rpx;
|
||||||
|
height: 50rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disContT1 {
|
||||||
|
width: 400rpx;
|
||||||
|
height: 50rpx;
|
||||||
|
// background-color: green;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disContT2 {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 50rpx;
|
||||||
|
line-height: 50rpx;
|
||||||
|
// background-color: gold;
|
||||||
|
font-size: 30rpx;
|
||||||
|
text-align: end;
|
||||||
|
color: white;
|
||||||
|
font-weight: bolder;
|
||||||
|
font-style: oblique 20deg;
|
||||||
|
letter-spacing: .1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disContT1P {
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disContT1End {
|
||||||
|
// width: 180rpx;
|
||||||
|
padding: 0 10rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
line-height: 28rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
background-color: white;
|
||||||
|
color: #ff3000;
|
||||||
|
font-size: 23rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
margin-left: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disContB {
|
||||||
|
width: 680rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 20rpx;
|
||||||
|
color: white;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disContB1 {
|
||||||
|
width: 300rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
line-height: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disContB2 {
|
||||||
|
width: 300rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
line-height: 40rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -118,7 +118,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive } 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';
|
||||||
|
@ -277,7 +277,15 @@
|
||||||
if (code !== 0) {
|
if (code !== 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state.pagination.list = _.concat(state.pagination.list, data.list);
|
// 使用 map 提取每个对象的 id 属性
|
||||||
|
const ids = data.list.map(item => item.id);
|
||||||
|
// 使用 join 方法将 id 数组连接成一个用逗号分隔的字符串
|
||||||
|
const idsString = ids.join(',');
|
||||||
|
// 获取结算信息
|
||||||
|
settleData.value = await getSettlementByIds(idsString)
|
||||||
|
// 处理获得的数据
|
||||||
|
const ms = enrichDataWithSkus(data.list,settleData.value)
|
||||||
|
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';
|
||||||
mountMasonry();
|
mountMasonry();
|
||||||
|
@ -292,6 +300,55 @@
|
||||||
getList(state.currentSort, state.currentOrder);
|
getList(state.currentSort, state.currentOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//获取结算信息
|
||||||
|
const settleData = ref()
|
||||||
|
async function getSettlementByIds(ids) {
|
||||||
|
const { data } = await SpuApi.getSettlementProduct(ids);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
//计算展示价格的函数
|
||||||
|
function enrichDataWithSkus(data, array) {
|
||||||
|
// 创建一个映射,以 id 为键,存储 data 数组中的对象
|
||||||
|
const dataMap = new Map(data.map(item => [item.id, { ...item }]));
|
||||||
|
|
||||||
|
// 遍历 array 数组
|
||||||
|
array.forEach(item => {
|
||||||
|
// 初始化 discountPrice 和 vipPrice 为 null
|
||||||
|
let discountPrice = null;
|
||||||
|
let vipPrice = null;
|
||||||
|
let foundType4 = false;
|
||||||
|
let foundType6 = false;
|
||||||
|
|
||||||
|
// 遍历 skus 数组,寻找 type 为 4 和 6 的首个条目
|
||||||
|
item.skus.forEach(sku => {
|
||||||
|
if (!foundType4 && sku.type === 4) {
|
||||||
|
discountPrice = sku.price;
|
||||||
|
foundType4 = true;
|
||||||
|
}
|
||||||
|
if (!foundType6 && sku.type === 6) {
|
||||||
|
vipPrice = sku.price;
|
||||||
|
foundType6 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果已经找到 type 为 4 和 6 的条目,则不需要继续遍历
|
||||||
|
if (foundType4 && foundType6) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新 dataMap 中对应的对象
|
||||||
|
if (dataMap.has(item.id)) {
|
||||||
|
dataMap.get(item.id).discountPrice = discountPrice;
|
||||||
|
dataMap.get(item.id).vipPrice = vipPrice;
|
||||||
|
dataMap.get(item.id).reward = item.reward;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 返回更新后的数据数组
|
||||||
|
return Array.from(dataMap.values());
|
||||||
|
}
|
||||||
|
|
||||||
onLoad((options) => {
|
onLoad((options) => {
|
||||||
state.categoryId = options.categoryId;
|
state.categoryId = options.categoryId;
|
||||||
state.keyword = options.keyword;
|
state.keyword = options.keyword;
|
||||||
|
|
|
@ -6,26 +6,13 @@
|
||||||
<!-- 骨架屏 -->
|
<!-- 骨架屏 -->
|
||||||
<detailSkeleton v-if="state.skeletonLoading" />
|
<detailSkeleton v-if="state.skeletonLoading" />
|
||||||
<!-- 下架/售罄提醒 -->
|
<!-- 下架/售罄提醒 -->
|
||||||
<s-empty
|
<s-empty v-else-if="state.goodsInfo === null || state.goodsInfo.activity_type !== 'seckill'" text="活动不存在或已结束"
|
||||||
v-else-if="state.goodsInfo === null || state.goodsInfo.activity_type !== 'seckill'"
|
icon="/static/soldout-empty.png" showAction actionText="再逛逛" actionUrl="/pages/goods/list" />
|
||||||
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
|
<su-swiper class="ss-m-b-14" isPreview :list="state.goodsSwiper" dotStyle="tag" imageMode="widthFix"
|
||||||
class="ss-m-b-14"
|
dotCur="bg-mask-40" :seizeHeight="750" />
|
||||||
isPreview
|
|
||||||
:list="state.goodsSwiper"
|
|
||||||
dotStyle="tag"
|
|
||||||
imageMode="widthFix"
|
|
||||||
dotCur="bg-mask-40"
|
|
||||||
:seizeHeight="750"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 价格+标题 -->
|
<!-- 价格+标题 -->
|
||||||
<view class="title-card ss-m-y-14 ss-m-x-20 ss-p-x-20 ss-p-y-34">
|
<view class="title-card ss-m-y-14 ss-m-x-20 ss-p-x-20 ss-p-y-34">
|
||||||
|
@ -63,7 +50,7 @@
|
||||||
<detail-progress :percent="state.percent" />
|
<detail-progress :percent="state.percent" />
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="title-text ss-line-2 ss-m-b-6">{{ state.goodsInfo?.name }}</view>
|
<view class="title-text ss-line-2 ss-m-b-6">{{ state.goodsInfo.name || '' }}</view>
|
||||||
<view class="subtitle-text ss-line-1">{{ state.goodsInfo.introduction }}</view>
|
<view class="subtitle-text ss-line-1">{{ state.goodsInfo.introduction }}</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
@ -72,14 +59,9 @@
|
||||||
<detail-cell-sku :sku="state.selectedSku" @tap="state.showSelectSku = true" />
|
<detail-cell-sku :sku="state.selectedSku" @tap="state.showSelectSku = true" />
|
||||||
</view>
|
</view>
|
||||||
<!-- 规格与数量弹框 -->
|
<!-- 规格与数量弹框 -->
|
||||||
<s-select-seckill-sku
|
<s-select-seckill-sku v-model="state.goodsInfo" :show="state.showSelectSku"
|
||||||
v-model="state.goodsInfo"
|
:single-limit-count="activity.singleLimitCount" @buy="onBuy" @change="onSkuChange"
|
||||||
:show="state.showSelectSku"
|
@close="state.showSelectSku = false" />
|
||||||
:single-limit-count="activity.singleLimitCount"
|
|
||||||
@buy="onBuy"
|
|
||||||
@change="onSkuChange"
|
|
||||||
@close="state.showSelectSku = false"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 评价 -->
|
<!-- 评价 -->
|
||||||
|
@ -91,36 +73,25 @@
|
||||||
<detail-tabbar v-model="state.goodsInfo">
|
<detail-tabbar v-model="state.goodsInfo">
|
||||||
<!-- TODO: 缺货中 已售罄 判断 设计-->
|
<!-- TODO: 缺货中 已售罄 判断 设计-->
|
||||||
<view class="buy-box ss-flex ss-col-center ss-p-r-20">
|
<view class="buy-box ss-flex ss-col-center ss-p-r-20">
|
||||||
<button
|
<button class="ss-reset-button origin-price-btn ss-flex-col" v-if="state.goodsInfo.marketPrice"
|
||||||
class="ss-reset-button origin-price-btn ss-flex-col"
|
@tap="sheep.$router.go('/pages/goods/index', { id: state.goodsInfo.id })">
|
||||||
v-if="state.goodsInfo.marketPrice"
|
|
||||||
@tap="sheep.$router.go('/pages/goods/index', { id: state.goodsInfo.id })"
|
|
||||||
>
|
|
||||||
<view>
|
<view>
|
||||||
<view class="btn-price">{{ fen2yuan(state.goodsInfo.marketPrice) }}</view>
|
<view class="btn-price">{{ fen2yuan(state.goodsInfo.marketPrice) }}</view>
|
||||||
<view>原价购买</view>
|
<view>原价购买</view>
|
||||||
</view>
|
</view>
|
||||||
</button>
|
</button>
|
||||||
<button v-else class="ss-reset-button origin-price-btn ss-flex-col">
|
<button v-else class="ss-reset-button origin-price-btn ss-flex-col">
|
||||||
<view
|
<view class="no-original" :class="
|
||||||
class="no-original"
|
|
||||||
:class="
|
|
||||||
state.goodsInfo.stock === 0 || timeStatusEnum !== TimeStatusEnum.STARTED ? '' : ''
|
state.goodsInfo.stock === 0 || timeStatusEnum !== TimeStatusEnum.STARTED ? '' : ''
|
||||||
"
|
">
|
||||||
>
|
|
||||||
秒杀价
|
秒杀价
|
||||||
</view>
|
</view>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button class="ss-reset-button btn-box ss-flex-col" @tap="state.showSelectSku = true" :class="
|
||||||
class="ss-reset-button btn-box ss-flex-col"
|
|
||||||
@tap="state.showSelectSku = true"
|
|
||||||
:class="
|
|
||||||
timeStatusEnum === TimeStatusEnum.STARTED && state.goodsInfo.stock != 0
|
timeStatusEnum === TimeStatusEnum.STARTED && state.goodsInfo.stock != 0
|
||||||
? 'check-btn-box'
|
? 'check-btn-box'
|
||||||
: 'disabled-btn-box'
|
: 'disabled-btn-box'
|
||||||
"
|
" :disabled="state.goodsInfo.stock === 0 || timeStatusEnum !== TimeStatusEnum.STARTED">
|
||||||
:disabled="state.goodsInfo.stock === 0 || timeStatusEnum !== TimeStatusEnum.STARTED"
|
|
||||||
>
|
|
||||||
<view class="btn-price">{{ fen2yuan(state.goodsInfo.price) }}</view>
|
<view class="btn-price">{{ fen2yuan(state.goodsInfo.price) }}</view>
|
||||||
<view v-if="timeStatusEnum === TimeStatusEnum.STARTED">
|
<view v-if="timeStatusEnum === TimeStatusEnum.STARTED">
|
||||||
<view v-if="state.goodsInfo.stock === 0">已售罄</view>
|
<view v-if="state.goodsInfo.stock === 0">已售罄</view>
|
||||||
|
@ -135,11 +106,26 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, computed, ref } from 'vue';
|
import {
|
||||||
import { onLoad, onPageScroll } from '@dcloudio/uni-app';
|
reactive,
|
||||||
|
computed,
|
||||||
|
ref,
|
||||||
|
unref
|
||||||
|
} from 'vue';
|
||||||
|
import {
|
||||||
|
onLoad,
|
||||||
|
onPageScroll
|
||||||
|
} from '@dcloudio/uni-app';
|
||||||
import sheep from '@/sheep';
|
import sheep from '@/sheep';
|
||||||
import { isEmpty, min } from 'lodash-es';
|
import {
|
||||||
import { useDurationTime, formatGoodsSwiper, fen2yuan } from '@/sheep/hooks/useGoods';
|
isEmpty,
|
||||||
|
min
|
||||||
|
} from 'lodash-es';
|
||||||
|
import {
|
||||||
|
useDurationTime,
|
||||||
|
formatGoodsSwiper,
|
||||||
|
fen2yuan
|
||||||
|
} 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';
|
||||||
import detailTabbar from './components/detail/detail-tabbar.vue';
|
import detailTabbar from './components/detail/detail-tabbar.vue';
|
||||||
|
@ -149,7 +135,10 @@
|
||||||
import detailProgress from './components/detail/detail-progress.vue';
|
import detailProgress from './components/detail/detail-progress.vue';
|
||||||
import SeckillApi from '@/sheep/api/promotion/seckill';
|
import SeckillApi from '@/sheep/api/promotion/seckill';
|
||||||
import SpuApi from '@/sheep/api/product/spu';
|
import SpuApi from '@/sheep/api/product/spu';
|
||||||
import { getTimeStatusEnum, TimeStatusEnum } from '@/sheep/util/const';
|
import {
|
||||||
|
getTimeStatusEnum,
|
||||||
|
TimeStatusEnum
|
||||||
|
} from '@/sheep/util/const';
|
||||||
|
|
||||||
const headerBg = sheep.$url.css('/static/img/shop/goods/seckill-bg.png');
|
const headerBg = sheep.$url.css('/static/img/shop/goods/seckill-bg.png');
|
||||||
const btnBg = sheep.$url.css('/static/img/shop/goods/seckill-btn.png');
|
const btnBg = sheep.$url.css('/static/img/shop/goods/seckill-btn.png');
|
||||||
|
@ -186,53 +175,53 @@
|
||||||
order_type: 'goods',
|
order_type: 'goods',
|
||||||
buy_type: 'seckill',
|
buy_type: 'seckill',
|
||||||
seckillActivityId: activity.value.id,
|
seckillActivityId: activity.value.id,
|
||||||
items: [
|
items: [{
|
||||||
{
|
skuId: sku.id,
|
||||||
skuId: sku.id,
|
count: sku.count,
|
||||||
count: sku.count,
|
}, ],
|
||||||
},
|
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分享信息 TODO 芋艿:待接入
|
// 分享信息
|
||||||
const shareInfo = computed(() => {
|
const shareInfo = computed(() => {
|
||||||
if (isEmpty(activity)) return {};
|
if (isEmpty(unref(activity))) return {};
|
||||||
return sheep.$platform.share.getShareInfo(
|
return sheep.$platform.share.getShareInfo({
|
||||||
{
|
title: activity.value.name,
|
||||||
title: activity.value.name,
|
image: sheep.$url.cdn(state.goodsInfo.picUrl),
|
||||||
image: sheep.$url.cdn(state.goodsInfo.picUrl),
|
params: {
|
||||||
params: {
|
page: '4',
|
||||||
page: '4',
|
query: activity.value.id,
|
||||||
query: activity.value.id,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
}, {
|
||||||
type: 'goods', // 商品海报
|
type: 'goods', // 商品海报
|
||||||
title: activity.value.name, // 商品标题
|
title: activity.value.name, // 商品标题
|
||||||
image: sheep.$url.cdn(state.goodsInfo.picUrl), // 商品主图
|
image: sheep.$url.cdn(state.goodsInfo.picUrl), // 商品主图
|
||||||
price: state.goodsInfo.price, // 商品价格
|
price: state.goodsInfo.price, // 商品价格
|
||||||
marketPrice: state.goodsInfo.marketPrice, // 商品原价
|
marketPrice: state.goodsInfo.marketPrice, // 商品原价
|
||||||
},
|
}, );
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const activity = ref();
|
const activity = ref();
|
||||||
const timeStatusEnum = ref('');
|
const timeStatusEnum = ref('');
|
||||||
|
|
||||||
// 查询活动
|
// 查询活动
|
||||||
const getActivity = async (id) => {
|
const getActivity = async (id) => {
|
||||||
const { data } = await SeckillApi.getSeckillActivity(id);
|
const {
|
||||||
|
data
|
||||||
|
} = await SeckillApi.getSeckillActivity(id);
|
||||||
activity.value = data;
|
activity.value = data;
|
||||||
timeStatusEnum.value = getTimeStatusEnum(activity.startTime, activity.endTime);
|
timeStatusEnum.value = getTimeStatusEnum(activity.value.startTime, activity.value.endTime);
|
||||||
|
state.percent = 100 - data.stock / data.totalStock * 100;
|
||||||
// 查询商品
|
// 查询商品
|
||||||
await getSpu(data.spuId);
|
await getSpu(data.spuId);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 查询商品
|
||||||
const getSpu = async (id) => {
|
const getSpu = async (id) => {
|
||||||
const { data } = await SpuApi.getSpuDetail(id);
|
const {
|
||||||
// 模拟
|
data
|
||||||
|
} = await SpuApi.getSpuDetail(id);
|
||||||
data.activity_type = 'seckill';
|
data.activity_type = 'seckill';
|
||||||
state.goodsInfo = data;
|
state.goodsInfo = data;
|
||||||
// 处理轮播图
|
// 处理轮播图
|
||||||
|
@ -283,6 +272,7 @@
|
||||||
.disabled-btn-box[disabled] {
|
.disabled-btn-box[disabled] {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.detail-card {
|
.detail-card {
|
||||||
background-color: $white;
|
background-color: $white;
|
||||||
margin: 14rpx 20rpx;
|
margin: 14rpx 20rpx;
|
||||||
|
@ -373,6 +363,7 @@
|
||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
|
|
||||||
.countdown-h {
|
.countdown-h {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
font-family: OPPOSANS;
|
font-family: OPPOSANS;
|
||||||
|
@ -383,6 +374,7 @@
|
||||||
background: rgba(#000000, 0.1);
|
background: rgba(#000000, 0.1);
|
||||||
border-radius: 6rpx;
|
border-radius: 6rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.countdown-num {
|
.countdown-num {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
font-family: OPPOSANS;
|
font-family: OPPOSANS;
|
||||||
|
@ -466,6 +458,7 @@
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
border-radius: 0px 40rpx 40rpx 0px;
|
border-radius: 0px 40rpx 40rpx 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-price {
|
.btn-price {
|
||||||
font-family: OPPOSANS;
|
font-family: OPPOSANS;
|
||||||
|
|
||||||
|
@ -483,6 +476,7 @@
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|
||||||
.no-original {
|
.no-original {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
}
|
}
|
||||||
|
@ -553,4 +547,4 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
|
@ -0,0 +1,263 @@
|
||||||
|
<!-- 下单界面,收货地址 or 自提门店的选择组件 -->
|
||||||
|
<template>
|
||||||
|
<view class="allAddress" :style="state.isPickUp ? '':'padding-top:10rpx;'">
|
||||||
|
<view class="nav flex flex-wrap">
|
||||||
|
<view class="item font-color" :class="state.deliveryType === 1 ? 'on' : 'on2'"
|
||||||
|
@tap="switchDeliveryType(1)" v-if='state.isPickUp' />
|
||||||
|
<view class="item font-color" :class="state.deliveryType === 2 ? 'on' : 'on2'"
|
||||||
|
@tap="switchDeliveryType(2)" v-if='state.isPickUp' />
|
||||||
|
</view>
|
||||||
|
<!-- 情况一:收货地址的选择 -->
|
||||||
|
<view class='address flex flex-wrap flex-center ss-row-between' @tap='onSelectAddress' v-if='state.deliveryType === 1'
|
||||||
|
:style="state.isPickUp ? '':'border-top-left-radius: 14rpx;border-top-right-radius: 14rpx;'">
|
||||||
|
<view class='addressCon' v-if="state.addressInfo.name">
|
||||||
|
<view class='name'>{{ state.addressInfo.name }}
|
||||||
|
<text class='phone'>{{ state.addressInfo.mobile }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex flex-wrap">
|
||||||
|
<text class='default font-color' v-if="state.addressInfo.defaultStatus">[默认]</text>
|
||||||
|
<text class="line2">{{ state.addressInfo.areaName }} {{ state.addressInfo.detailAddress }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class='addressCon' v-else>
|
||||||
|
<view class='setaddress'>设置收货地址</view>
|
||||||
|
</view>
|
||||||
|
<view class='iconfont'>
|
||||||
|
<view class="ss-rest-button">
|
||||||
|
<text class="_icon-forward" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 情况二:门店的选择 -->
|
||||||
|
<view class='address flex flex-wrap flex-center ss-row-between' v-else @tap="onSelectAddress">
|
||||||
|
<view class='addressCon' v-if="state.pickUpInfo.name">
|
||||||
|
<view class='name'>{{ state.pickUpInfo.name }}
|
||||||
|
<text class='phone'>{{ state.pickUpInfo.phone }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="line1"> {{ state.pickUpInfo.areaName }}{{ ', ' + state.pickUpInfo.detailAddress }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class='addressCon' v-else>
|
||||||
|
<view class='setaddress'>选择自提门店</view>
|
||||||
|
</view>
|
||||||
|
<view class='iconfont'>
|
||||||
|
<view class="ss-rest-button">
|
||||||
|
<text class="_icon-forward" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class='line'>
|
||||||
|
<image :src="sheep.$url.static('/static/images/line.png', 'local')" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import sheep from '@/sheep';
|
||||||
|
import { isEmpty } from 'lodash-es';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Object,
|
||||||
|
default() {},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const emits = defineEmits(['update:modelValue','change']);
|
||||||
|
|
||||||
|
// computed 解决父子组件双向数据同步
|
||||||
|
const state = computed({
|
||||||
|
get(){
|
||||||
|
return new Proxy(props.modelValue, {
|
||||||
|
set(obj, name, val) {
|
||||||
|
emits('update:modelValue', {
|
||||||
|
...obj,
|
||||||
|
[name]: val,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
set(val){
|
||||||
|
emits('update:modelValue', val);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 选择地址
|
||||||
|
function onSelectAddress() {
|
||||||
|
let emitName = 'SELECT_ADDRESS'
|
||||||
|
let addressPage = '/pages/user/address/list?type=select';
|
||||||
|
if (state.value.deliveryType === 2){
|
||||||
|
emitName = 'SELECT_PICK_UP_INFO'
|
||||||
|
addressPage = '/pages/user/goods_details_store/index'
|
||||||
|
}
|
||||||
|
uni.$once(emitName, (e) => {
|
||||||
|
changeConsignee(e.addressInfo);
|
||||||
|
});
|
||||||
|
sheep.$router.go(addressPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更改收货人地址&计算订单信息
|
||||||
|
async function changeConsignee(addressInfo = {}) {
|
||||||
|
if (!isEmpty(addressInfo)) {
|
||||||
|
if (state.value.deliveryType === 1){
|
||||||
|
state.value.addressInfo = addressInfo;
|
||||||
|
}
|
||||||
|
if (state.value.deliveryType === 2){
|
||||||
|
state.value.pickUpInfo = addressInfo;
|
||||||
|
}
|
||||||
|
emits('change')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 收货方式切换
|
||||||
|
const switchDeliveryType = (type) =>{
|
||||||
|
state.value.deliveryType = type;
|
||||||
|
emits('change')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.allAddress .font-color{
|
||||||
|
color: #E93323!important
|
||||||
|
}
|
||||||
|
.line2{
|
||||||
|
width: 504rpx;
|
||||||
|
}
|
||||||
|
.textR {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line {
|
||||||
|
width: 100%;
|
||||||
|
height: 3rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address {
|
||||||
|
padding: 28rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address .addressCon {
|
||||||
|
width: 596rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address .addressCon .name {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #282828;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address .addressCon .name .phone {
|
||||||
|
margin-left: 50rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address .addressCon .default {
|
||||||
|
margin-right: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address .addressCon .setaddress {
|
||||||
|
color: #333;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address .iconfont {
|
||||||
|
font-size: 35rpx;
|
||||||
|
color: #707070;
|
||||||
|
}
|
||||||
|
|
||||||
|
.allAddress {
|
||||||
|
width: 100%;
|
||||||
|
background: linear-gradient(to bottom, #e93323 0%, #f5f5f5 100%);
|
||||||
|
// background-image: linear-gradient(to bottom, #e93323 0%, #f5f5f5 100%);
|
||||||
|
// background-image: -webkit-linear-gradient(to bottom, #e93323 0%, #f5f5f5 100%);
|
||||||
|
// background-image: -moz-linear-gradient(to bottom, #e93323 0%, #f5f5f5 100%);
|
||||||
|
//padding: 100rpx 30rpx 0 30rpx;
|
||||||
|
padding-top: 100rpx;
|
||||||
|
padding-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.allAddress .nav {
|
||||||
|
width: 690rpx;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.allAddress .nav .item {
|
||||||
|
width: 334rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.allAddress .nav .item.on {
|
||||||
|
position: relative;
|
||||||
|
width: 230rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.allAddress .nav .item.on::before {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
content: "快递配送";
|
||||||
|
font-size: 28rpx;
|
||||||
|
display: block;
|
||||||
|
height: 0;
|
||||||
|
width: 336rpx;
|
||||||
|
border-width: 0 20rpx 80rpx 0;
|
||||||
|
border-style: none solid solid;
|
||||||
|
border-color: transparent transparent #fff;
|
||||||
|
z-index: 2;
|
||||||
|
border-radius: 14rpx 36rpx 0 0;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 80rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.allAddress .nav .item:nth-of-type(2).on::before {
|
||||||
|
content: "到店自提";
|
||||||
|
border-width: 0 0 80rpx 20rpx;
|
||||||
|
border-radius: 36rpx 14rpx 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.allAddress .nav .item.on2 {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.allAddress .nav .item.on2::before {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
content: "到店自提";
|
||||||
|
font-size: 28rpx;
|
||||||
|
display: block;
|
||||||
|
height: 0;
|
||||||
|
width: 401rpx;
|
||||||
|
border-width: 0 0 60rpx 60rpx;
|
||||||
|
border-style: none solid solid;
|
||||||
|
border-color: transparent transparent #f7c1bd;
|
||||||
|
border-radius: 36rpx 14rpx 0 0;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.allAddress .nav .item:nth-of-type(1).on2::before {
|
||||||
|
content: "快递配送";
|
||||||
|
border-width: 0 60rpx 60rpx 0;
|
||||||
|
border-radius: 14rpx 36rpx 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.allAddress .address {
|
||||||
|
width: 690rpx;
|
||||||
|
max-height: 180rpx;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.allAddress .line {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,36 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<s-layout title="确认订单">
|
<s-layout title="确认订单">
|
||||||
<!-- TODO:这个判断先删除 v-if="state.orderInfo.need_address === 1" -->
|
<!-- 头部地址选择【配送地址】【自提地址】 -->
|
||||||
<view class="bg-white address-box ss-m-b-14 ss-r-b-10" @tap="onSelectAddress">
|
<AddressSelection v-model="addressState" @change="getOrderInfo()" />
|
||||||
<s-address-item :item="state.addressInfo" :hasBorderBottom="false">
|
|
||||||
<view class="ss-rest-button">
|
|
||||||
<text class="_icon-forward" />
|
|
||||||
</view>
|
|
||||||
</s-address-item>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 商品信息 -->
|
<!-- 商品信息 -->
|
||||||
<view class="order-card-box ss-m-b-14">
|
<view class="order-card-box ss-m-b-14">
|
||||||
<s-goods-item
|
<s-goods-item v-for="item in state.orderInfo.items" :key="item.skuId" :img="item.picUrl"
|
||||||
v-for="item in state.orderInfo.items"
|
:title="item.spuName" :skuText="item.properties.map((property) => property.valueName).join(' ')"
|
||||||
:key="item.skuId"
|
:price="item.price" :num="item.count" marginBottom="10" />
|
||||||
:img="item.picUrl"
|
|
||||||
:title="item.spuName"
|
|
||||||
:skuText="item.properties.map((property) => property.valueName).join(' ')"
|
|
||||||
:price="item.price"
|
|
||||||
:num="item.count"
|
|
||||||
marginBottom="10"
|
|
||||||
/>
|
|
||||||
<view class="order-item ss-flex ss-col-center ss-row-between ss-p-x-20 bg-white ss-r-10">
|
<view class="order-item ss-flex ss-col-center ss-row-between ss-p-x-20 bg-white ss-r-10">
|
||||||
<view class="item-title">订单备注</view>
|
<view class="item-title">订单备注</view>
|
||||||
<view class="ss-flex ss-col-center">
|
<view class="ss-flex ss-col-center">
|
||||||
<uni-easyinput
|
<uni-easyinput maxlength="20" placeholder="建议留言前先与商家沟通" v-model="state.orderPayload.remark"
|
||||||
maxlength="20"
|
:inputBorder="false" :clearable="false" />
|
||||||
placeholder="建议留言前先与商家沟通"
|
|
||||||
v-model="state.orderPayload.remark"
|
|
||||||
:inputBorder="false"
|
|
||||||
:clearable="false"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
@ -46,67 +28,71 @@
|
||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- TODO 芋艿:接入积分 -->
|
<view class="order-item ss-flex ss-col-center ss-row-between" v-if="state.orderInfo.type === 0">
|
||||||
<view
|
<view class="item-title">积分抵扣</view>
|
||||||
class="order-item ss-flex ss-col-center ss-row-between"
|
|
||||||
v-if="state.orderPayload.order_type === 'score'"
|
|
||||||
>
|
|
||||||
<view class="item-title">扣除积分</view>
|
|
||||||
<view class="ss-flex ss-col-center">
|
<view class="ss-flex ss-col-center">
|
||||||
<image
|
{{ state.pointStatus ? '剩余积分' : '当前积分' }}
|
||||||
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')"
|
<image :src="sheep.$url.static('/static/img/shop/goods/score1.svg')" class="score-img" />
|
||||||
class="score-img"
|
<text class="item-value ss-m-r-24">
|
||||||
/>
|
{{ state.pointStatus ? state.orderInfo.totalPoint - state.orderInfo.usePoint : (state.orderInfo.totalPoint || 0) }}
|
||||||
<text class="item-value ss-m-r-24">{{ state.orderInfo.score_amount }}</text>
|
</text>
|
||||||
|
<checkbox-group @change="changeIntegral">
|
||||||
|
<checkbox :checked='state.pointStatus'
|
||||||
|
:disabled="!state.orderInfo.totalPoint || state.orderInfo.totalPoint <= 0" />
|
||||||
|
</checkbox-group>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="order-item ss-flex ss-col-center ss-row-between">
|
<!-- 快递配置时,信息的展示 -->
|
||||||
|
<view class="order-item ss-flex ss-col-center ss-row-between" v-if='addressState.deliveryType === 1'>
|
||||||
<view class="item-title">运费</view>
|
<view class="item-title">运费</view>
|
||||||
<view class="ss-flex ss-col-center">
|
<view class="ss-flex ss-col-center">
|
||||||
<text class="item-value ss-m-r-24">
|
<text class="item-value ss-m-r-24" v-if="state.orderInfo.price.deliveryPrice > 0">
|
||||||
+¥{{ fen2yuan(state.orderInfo.price.deliveryPrice) }}
|
+¥{{ fen2yuan(state.orderInfo.price.deliveryPrice) }}
|
||||||
</text>
|
</text>
|
||||||
|
<view class='item-value ss-m-r-24' v-else>免运费</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 门店自提时,需要填写姓名和手机号 -->
|
||||||
|
<view class="order-item ss-flex ss-col-center ss-row-between" v-if='addressState.deliveryType === 2'>
|
||||||
|
<view class="item-title">联系人</view>
|
||||||
|
<view class="ss-flex ss-col-center">
|
||||||
|
<uni-easyinput maxlength="20" placeholder="请填写您的联系姓名" v-model="addressState.receiverName"
|
||||||
|
:inputBorder="false" :clearable="false" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="order-item ss-flex ss-col-center ss-row-between" v-if='addressState.deliveryType === 2'>
|
||||||
|
<view class="item-title">联系电话</view>
|
||||||
|
<view class="ss-flex ss-col-center">
|
||||||
|
<uni-easyinput maxlength="20" placeholder="请填写您的联系电话" v-model="addressState.receiverMobile"
|
||||||
|
:inputBorder="false" :clearable="false" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 优惠劵:只有 type = 0 普通订单(非拼团、秒杀、砍价),才可以使用优惠劵 -->
|
<!-- 优惠劵:只有 type = 0 普通订单(非拼团、秒杀、砍价),才可以使用优惠劵 -->
|
||||||
<view
|
<view class="order-item ss-flex ss-col-center ss-row-between" v-if="state.orderInfo.type === 0">
|
||||||
class="order-item ss-flex ss-col-center ss-row-between"
|
|
||||||
v-if="state.orderInfo.type === 0"
|
|
||||||
>
|
|
||||||
<view class="item-title">优惠券</view>
|
<view class="item-title">优惠券</view>
|
||||||
<view class="ss-flex ss-col-center" @tap="state.showCoupon = true">
|
<view class="ss-flex ss-col-center" @tap="state.showCoupon = true">
|
||||||
<text class="item-value text-red" v-if="state.orderPayload.couponId > 0">
|
<text class="item-value text-red" v-if="state.orderPayload.couponId > 0">
|
||||||
-¥{{ fen2yuan(state.orderInfo.price.couponPrice) }}
|
-¥{{ fen2yuan(state.orderInfo.price.couponPrice) }}
|
||||||
</text>
|
</text>
|
||||||
<text
|
<text class="item-value" :class="couponNumber > 0 ? 'text-red' : 'text-disabled'" v-else>
|
||||||
class="item-value"
|
|
||||||
:class="state.couponInfo.length > 0 ? 'text-red' : 'text-disabled'"
|
|
||||||
v-else
|
|
||||||
>
|
|
||||||
{{
|
{{
|
||||||
state.couponInfo.length > 0 ? state.couponInfo.length + ' 张可用' : '暂无可用优惠券'
|
couponNumber > 0 ? couponNumber + ' 张可用' : '暂无可用优惠券'
|
||||||
}}
|
}}
|
||||||
</text>
|
</text>
|
||||||
<text class="_icon-forward item-icon" />
|
<text class="_icon-forward item-icon" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view class="order-item ss-flex ss-col-center ss-row-between"
|
||||||
class="order-item ss-flex ss-col-center ss-row-between"
|
v-if="state.orderInfo.price.discountPrice > 0">
|
||||||
v-if="state.orderInfo.price.discountPrice > 0"
|
|
||||||
>
|
|
||||||
<view class="item-title">活动优惠</view>
|
<view class="item-title">活动优惠</view>
|
||||||
<view class="ss-flex ss-col-center">
|
<view class="ss-flex ss-col-center" @tap="state.showDiscount = true">
|
||||||
<!-- @tap="state.showDiscount = true" TODO 芋艿:后续要把优惠信息打进去 -->
|
|
||||||
<text class="item-value text-red">
|
<text class="item-value text-red">
|
||||||
-¥{{ fen2yuan(state.orderInfo.price.discountPrice) }}
|
-¥{{ fen2yuan(state.orderInfo.price.discountPrice) }}
|
||||||
</text>
|
</text>
|
||||||
<text class="_icon-forward item-icon" />
|
<text class="_icon-forward item-icon" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view class="order-item ss-flex ss-col-center ss-row-between" v-if="state.orderInfo.price.vipPrice > 0">
|
||||||
class="order-item ss-flex ss-col-center ss-row-between"
|
|
||||||
v-if="state.orderInfo.price.vipPrice > 0"
|
|
||||||
>
|
|
||||||
<view class="item-title">会员优惠</view>
|
<view class="item-title">会员优惠</view>
|
||||||
<view class="ss-flex ss-col-center">
|
<view class="ss-flex ss-col-center">
|
||||||
<text class="item-value text-red">
|
<text class="item-value text-red">
|
||||||
|
@ -120,24 +106,16 @@
|
||||||
共{{ state.orderInfo.items.reduce((acc, item) => acc + item.count, 0) }}件
|
共{{ state.orderInfo.items.reduce((acc, item) => acc + item.count, 0) }}件
|
||||||
</view>
|
</view>
|
||||||
<view>合计:</view>
|
<view>合计:</view>
|
||||||
<view class="total-num text-red"> ¥{{ fen2yuan(state.orderInfo.price.payPrice) }} </view>
|
<view class="total-num text-red"> ¥{{ fen2yuan(state.orderInfo.price.payPrice) }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 选择优惠券弹框 -->
|
<!-- 选择优惠券弹框 -->
|
||||||
<s-coupon-select
|
<s-coupon-select v-model="state.couponInfo" :show="state.showCoupon" @confirm="onSelectCoupon"
|
||||||
v-model="state.couponInfo"
|
@close="state.showCoupon = false" />
|
||||||
:show="state.showCoupon"
|
|
||||||
@confirm="onSelectCoupon"
|
|
||||||
@close="state.showCoupon = false"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 满额折扣弹框 TODO 芋艿:后续要把优惠信息打进去 -->
|
<!-- 满额折扣弹框 TODO 芋艿:后续要把优惠信息打进去 -->
|
||||||
<s-discount-list
|
<s-discount-list v-model="state.orderInfo" :show="state.showDiscount" @close="state.showDiscount = false" />
|
||||||
v-model="state.orderInfo"
|
|
||||||
:show="state.showDiscount"
|
|
||||||
@close="state.showDiscount = false"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 底部 -->
|
<!-- 底部 -->
|
||||||
<su-fixed bottom :opacity="false" bg="bg-white" placeholder :noFixed="false" :index="200">
|
<su-fixed bottom :opacity="false" bg="bg-white" placeholder :noFixed="false" :index="200">
|
||||||
|
@ -147,10 +125,7 @@
|
||||||
¥{{ fen2yuan(state.orderInfo.price.payPrice) }}
|
¥{{ fen2yuan(state.orderInfo.price.payPrice) }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<button
|
<button class="ss-reset-button ui-BG-Main-Gradient ss-r-40 submit-btn ui-Shadow-Main" @tap="onConfirm">
|
||||||
class="ss-reset-button ui-BG-Main-Gradient ss-r-40 submit-btn ui-Shadow-Main"
|
|
||||||
@tap="onConfirm"
|
|
||||||
>
|
|
||||||
提交订单
|
提交订单
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
|
@ -159,14 +134,20 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive } from 'vue';
|
import {
|
||||||
import { onLoad } from '@dcloudio/uni-app';
|
reactive,
|
||||||
|
ref
|
||||||
|
} from 'vue';
|
||||||
|
import {
|
||||||
|
onLoad
|
||||||
|
} from '@dcloudio/uni-app';
|
||||||
|
import AddressSelection from '@/pages/order/addressSelection.vue';
|
||||||
import sheep from '@/sheep';
|
import sheep from '@/sheep';
|
||||||
import { isEmpty } from 'lodash-es';
|
|
||||||
import OrderApi from '@/sheep/api/trade/order';
|
import OrderApi from '@/sheep/api/trade/order';
|
||||||
import CouponApi from '@/sheep/api/promotion/coupon';
|
import CouponApi from '@/sheep/api/promotion/coupon';
|
||||||
import { fen2yuan } from '@/sheep/hooks/useGoods';
|
import {
|
||||||
import { WxaSubscribeTemplate } from '@/sheep/util/const';
|
fen2yuan
|
||||||
|
} from '@/sheep/hooks/useGoods';
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
orderPayload: {},
|
orderPayload: {},
|
||||||
|
@ -174,27 +155,30 @@
|
||||||
items: [], // 商品项列表
|
items: [], // 商品项列表
|
||||||
price: {}, // 价格信息
|
price: {}, // 价格信息
|
||||||
},
|
},
|
||||||
addressInfo: {}, // 选择的收货地址
|
|
||||||
showCoupon: false, // 是否展示优惠劵
|
showCoupon: false, // 是否展示优惠劵
|
||||||
couponInfo: [], // 优惠劵列表
|
couponInfo: [], // 优惠劵列表
|
||||||
showDiscount: false, // 是否展示营销活动
|
showDiscount: false, // 是否展示营销活动
|
||||||
|
// ========== 积分 ==========
|
||||||
|
pointStatus: false, //是否使用积分
|
||||||
});
|
});
|
||||||
|
|
||||||
// 选择地址
|
const addressState = ref({
|
||||||
function onSelectAddress() {
|
addressInfo: {}, // 选择的收货地址
|
||||||
uni.$once('SELECT_ADDRESS', (e) => {
|
deliveryType: 1, // 收货方式 1 - 快递配送;2 - 门店自提
|
||||||
changeConsignee(e.addressInfo);
|
isPickUp: true, // 门店自提是否开启 TODO puhui999: 默认开启,看看后端有开关的话接入
|
||||||
});
|
pickUpInfo: {}, // 选择的自提门店信息
|
||||||
sheep.$router.go('/pages/user/address/list');
|
receiverName: '', // 收件人名称
|
||||||
}
|
receiverMobile: '', // 收件人手机
|
||||||
|
});
|
||||||
|
|
||||||
// 更改收货人地址&计算订单信息
|
// ========== 积分 ==========
|
||||||
async function changeConsignee(addressInfo = {}) {
|
/**
|
||||||
if (!isEmpty(addressInfo)) {
|
* 使用积分抵扣
|
||||||
state.addressInfo = addressInfo;
|
*/
|
||||||
}
|
const changeIntegral = async () => {
|
||||||
|
state.pointStatus = !state.pointStatus;
|
||||||
await getOrderInfo();
|
await getOrderInfo();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 选择优惠券
|
// 选择优惠券
|
||||||
async function onSelectCoupon(couponId) {
|
async function onSelectCoupon(couponId) {
|
||||||
|
@ -205,22 +189,46 @@
|
||||||
|
|
||||||
// 提交订单
|
// 提交订单
|
||||||
function onConfirm() {
|
function onConfirm() {
|
||||||
if (!state.addressInfo.id) {
|
if (addressState.value.deliveryType === 1 && !addressState.value.addressInfo.id) {
|
||||||
sheep.$helper.toast('请选择收货地址');
|
sheep.$helper.toast('请选择收货地址');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (addressState.value.deliveryType === 2) {
|
||||||
|
if (!addressState.value.pickUpInfo.id) {
|
||||||
|
sheep.$helper.toast('请选择自提门店地址');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (addressState.value.receiverName === '' || addressState.value.receiverMobile === '') {
|
||||||
|
sheep.$helper.toast('请填写联系人或联系人电话');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!/^[\u4e00-\u9fa5\w]{2,16}$/.test(addressState.value.receiverName)) {
|
||||||
|
sheep.$helper.toast('请填写您的真实姓名');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!/^1(3|4|5|7|8|9|6)\d{9}$/.test(addressState.value.receiverMobile)) {
|
||||||
|
sheep.$helper.toast('请填写正确的手机号');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
submitOrder();
|
submitOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建订单&跳转
|
// 创建订单&跳转
|
||||||
async function submitOrder() {
|
async function submitOrder() {
|
||||||
const { code, data } = await OrderApi.createOrder({
|
const {
|
||||||
|
code,
|
||||||
|
data
|
||||||
|
} = await OrderApi.createOrder({
|
||||||
items: state.orderPayload.items,
|
items: state.orderPayload.items,
|
||||||
couponId: state.orderPayload.couponId,
|
couponId: state.orderPayload.couponId,
|
||||||
remark: state.orderPayload.remark,
|
remark: state.orderPayload.remark,
|
||||||
addressId: state.addressInfo.id,
|
deliveryType: addressState.value.deliveryType,
|
||||||
deliveryType: 1, // TODO 芋艿:需要支持【门店自提】
|
addressId: addressState.value.addressInfo.id, // 收件地址编号
|
||||||
pointStatus: false, // TODO 芋艿:需要支持【积分选择】
|
pickUpStoreId: addressState.value.pickUpInfo.id, //自提门店编号
|
||||||
|
receiverName: addressState.value.receiverName, // 选择门店自提时,该字段为联系人名
|
||||||
|
receiverMobile: addressState.value.receiverMobile, // 选择门店自提时,该字段为联系人手机
|
||||||
|
pointStatus: state.pointStatus,
|
||||||
combinationActivityId: state.orderPayload.combinationActivityId,
|
combinationActivityId: state.orderPayload.combinationActivityId,
|
||||||
combinationHeadId: state.orderPayload.combinationHeadId,
|
combinationHeadId: state.orderPayload.combinationHeadId,
|
||||||
seckillActivityId: state.orderPayload.seckillActivityId,
|
seckillActivityId: state.orderPayload.seckillActivityId,
|
||||||
|
@ -242,29 +250,44 @@
|
||||||
// 检查库存 & 计算订单价格
|
// 检查库存 & 计算订单价格
|
||||||
async function getOrderInfo() {
|
async function getOrderInfo() {
|
||||||
// 计算价格
|
// 计算价格
|
||||||
const { data, code } = await OrderApi.settlementOrder({
|
const {
|
||||||
|
data,
|
||||||
|
code
|
||||||
|
} = await OrderApi.settlementOrder({
|
||||||
items: state.orderPayload.items,
|
items: state.orderPayload.items,
|
||||||
couponId: state.orderPayload.couponId,
|
couponId: state.orderPayload.couponId,
|
||||||
addressId: state.addressInfo.id,
|
deliveryType: addressState.value.deliveryType,
|
||||||
deliveryType: 1, // TODO 芋艿:需要支持【门店自提】
|
addressId: addressState.value.addressInfo.id, // 收件地址编号
|
||||||
pointStatus: false, // TODO 芋艿:需要支持【积分选择】
|
pickUpStoreId: addressState.value.pickUpInfo.id, //自提门店编号
|
||||||
|
receiverName: addressState.value.receiverName, // 选择门店自提时,该字段为联系人名
|
||||||
|
receiverMobile: addressState.value.receiverMobile, // 选择门店自提时,该字段为联系人手机
|
||||||
|
pointStatus: state.pointStatus,
|
||||||
combinationActivityId: state.orderPayload.combinationActivityId,
|
combinationActivityId: state.orderPayload.combinationActivityId,
|
||||||
combinationHeadId: state.orderPayload.combinationHeadId,
|
combinationHeadId: state.orderPayload.combinationHeadId,
|
||||||
seckillActivityId: state.orderPayload.seckillActivityId,
|
seckillActivityId: state.orderPayload.seckillActivityId,
|
||||||
});
|
});
|
||||||
if (code !== 0) {
|
if (code !== 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.navigateBack({
|
||||||
|
delta: 1
|
||||||
|
})
|
||||||
|
}, 1500)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state.orderInfo = data;
|
state.orderInfo = data;
|
||||||
// 设置收货地址
|
// 设置收货地址
|
||||||
if (state.orderInfo.address) {
|
if (state.orderInfo.address) {
|
||||||
state.addressInfo = state.orderInfo.address;
|
addressState.value.addressInfo = state.orderInfo.address;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取可用优惠券
|
// 获取可用优惠券
|
||||||
|
let couponNumber = ref(0)
|
||||||
async function getCoupons() {
|
async function getCoupons() {
|
||||||
const { code, data } = await CouponApi.getMatchCouponList(
|
const {
|
||||||
|
code,
|
||||||
|
data
|
||||||
|
} = await CouponApi.getMatchCouponList(
|
||||||
state.orderInfo.price.payPrice,
|
state.orderInfo.price.payPrice,
|
||||||
state.orderInfo.items.map((item) => item.spuId),
|
state.orderInfo.items.map((item) => item.spuId),
|
||||||
state.orderPayload.items.map((item) => item.skuId),
|
state.orderPayload.items.map((item) => item.skuId),
|
||||||
|
@ -272,6 +295,7 @@
|
||||||
);
|
);
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
state.couponInfo = data;
|
state.couponInfo = data;
|
||||||
|
couponNumber.value = state.couponInfo.filter(item => item.match).length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,4 +429,4 @@
|
||||||
font-size: 36rpx;
|
font-size: 36rpx;
|
||||||
color: #999999;
|
color: #999999;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
|
@ -13,6 +13,18 @@ const SpuApi = {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
// 获得商品结算信息
|
||||||
|
getSettlementProduct: (ids) => {
|
||||||
|
return request({
|
||||||
|
url: '/trade/order/settlementProduct',
|
||||||
|
method: 'GET',
|
||||||
|
params: { ids },
|
||||||
|
custom: {
|
||||||
|
showLoading: false,
|
||||||
|
showError: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
// 获得商品 SPU 分页
|
// 获得商品 SPU 分页
|
||||||
getSpuPage: (params) => {
|
getSpuPage: (params) => {
|
||||||
return request({
|
return request({
|
||||||
|
|
|
@ -2,22 +2,100 @@
|
||||||
<template>
|
<template>
|
||||||
<su-popup :show="show" type="bottom" round="20" @close="emits('close')" showClose>
|
<su-popup :show="show" type="bottom" round="20" @close="emits('close')" showClose>
|
||||||
<view class="model-box">
|
<view class="model-box">
|
||||||
<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>
|
||||||
<scroll-view
|
<view v-if="state.activityMap[state.activityInfo[0]?.id]?.reduc">
|
||||||
class="model-content ss-m-t-50"
|
<view class="titleLi">促销</view>
|
||||||
scroll-y
|
<scroll-view class="model-content" scroll-y :scroll-with-animation="false" :enable-back-to-top="true">
|
||||||
:scroll-with-animation="false"
|
<view class="actBox">
|
||||||
:enable-back-to-top="true"
|
<view class="boxCont ss-flex ss-col-top ss-m-b-40" @tap="onGoodsList(state.activityInfo[0])">
|
||||||
>
|
<view class="model-content-tag ss-flex ss-row-center">满减</view>
|
||||||
<view v-for="item in state.activityInfo" :key="item.id">
|
<view class="model-content-title">
|
||||||
<view class="ss-flex ss-col-top ss-m-b-40" @tap="onGoodsList(item)">
|
<view class="contBu">
|
||||||
<view class="model-content-tag ss-flex ss-row-center">满减</view>
|
<text v-for="(item,index) in state.activityMap[state.activityInfo[0]?.id]?.reduc"
|
||||||
<view class="ss-m-l-20 model-content-title ss-flex-1">
|
:key="index">满{{fen2yuan(item.discountPrice)}}元减{{fen2yuan(item.limit)}}元;</text>
|
||||||
<view class="ss-m-b-24" v-for="rule in state.activityMap[item.id]?.rules" :key="rule">
|
</view>
|
||||||
{{ formatRewardActivityRule(state.activityMap[item.id], rule) }}
|
<view class="ss-m-b-24 cotBu-txt">
|
||||||
|
{{formatDateRange(state.activityInfo[0]?.startTime,state.activityInfo[0]?.endTime)}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<text class="cicon-forward" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="actBox">
|
||||||
|
<view class="boxCont ss-flex ss-col-top ss-m-b-40" @tap="onGoodsList(state.activityInfo[0])">
|
||||||
|
<view class="model-content-tag ss-flex ss-row-center">包邮</view>
|
||||||
|
<view class="model-content-title">
|
||||||
|
<view class="contBu">
|
||||||
|
<text v-for="(item,index) in state.activityMap[state.activityInfo[0]?.id]?.ship"
|
||||||
|
:key="index" v-show="item.bull">满{{fen2yuan(item.discountPrice)}}元包邮;</text>
|
||||||
|
</view>
|
||||||
|
<view class="ss-m-b-24 cotBu-txt">
|
||||||
|
{{formatDateRange(state.activityInfo[0]?.startTime,state.activityInfo[0]?.endTime)}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<text class="cicon-forward" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="actBox">
|
||||||
|
<view class="boxCont ss-flex ss-col-top ss-m-b-40" @tap="onGoodsList(state.activityInfo[0])">
|
||||||
|
<view class="model-content-tag ss-flex ss-row-center">送积分</view>
|
||||||
|
<view class="model-content-title">
|
||||||
|
<view class="contBu">
|
||||||
|
<text v-for="(item,index) in state.activityMap[state.activityInfo[0]?.id]?.scor"
|
||||||
|
:key="index"
|
||||||
|
v-show="item.bull">满{{fen2yuan(item.discountPrice)}}元送{{item.value}}积分;</text>
|
||||||
|
</view>
|
||||||
|
<view class="ss-m-b-24 cotBu-txt">
|
||||||
|
{{formatDateRange(state.activityInfo[0]?.startTime,state.activityInfo[0]?.endTime)}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<text class="cicon-forward" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="actBox">
|
||||||
|
<view class="boxCont ss-flex ss-col-top ss-m-b-40" @tap="onGoodsList(state.activityInfo[0])">
|
||||||
|
<view class="model-content-tag ss-flex ss-row-center">送优惠券</view>
|
||||||
|
<view class="model-content-title">
|
||||||
|
<view class="contBu">
|
||||||
|
<text v-for="(item,index) in state.activityMap[state.activityInfo[0]?.id]?.cou"
|
||||||
|
:key="index"
|
||||||
|
v-show="item.bull">满{{fen2yuan(item.discountPrice)}}元送{{item.value}}张优惠券;</text>
|
||||||
|
</view>
|
||||||
|
<view class="ss-m-b-24 cotBu-txt">
|
||||||
|
{{formatDateRange(state.activityInfo[0]?.startTime,state.activityInfo[0]?.endTime)}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<text class="cicon-forward" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
<view class="titleLi">可领优惠券</view>
|
||||||
|
<scroll-view class="model-content" scroll-y :scroll-with-animation="false" :enable-back-to-top="true">
|
||||||
|
<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="model-content-tag2">
|
||||||
|
<view class="usePrice">
|
||||||
|
¥{{fen2yuan(item.discountPrice)}}
|
||||||
|
</view>
|
||||||
|
<view class="impose">
|
||||||
|
满¥{{fen2yuan(item.usePrice)}}可用
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<text class="cicon-forward" />
|
<view class="model-content-title2">
|
||||||
|
<view class="contBu">
|
||||||
|
{{item.name}}
|
||||||
|
</view>
|
||||||
|
<view class="ss-m-b-24 cotBu-txt">
|
||||||
|
{{item.validityType==1?formatDateRange(item.validStartTime,item.validEndTime) : '领取后'+item.fixedStartTerm+'-'+item.fixedEndTerm +'天可用'}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="coupon" @click.stop="getBuy(item.id)" v-if="item.canTake">
|
||||||
|
立即领取
|
||||||
|
</view>
|
||||||
|
<view class="coupon2" v-else>
|
||||||
|
已领取
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
@ -26,14 +104,21 @@
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import sheep from '@/sheep';
|
import sheep from '@/sheep';
|
||||||
import { computed, reactive, watch } from 'vue';
|
import {
|
||||||
|
computed,
|
||||||
|
reactive,
|
||||||
|
watch
|
||||||
|
} from 'vue';
|
||||||
import RewardActivityApi from '@/sheep/api/promotion/rewardActivity';
|
import RewardActivityApi from '@/sheep/api/promotion/rewardActivity';
|
||||||
import { formatRewardActivityRule } from '@/sheep/hooks/useGoods';
|
import {
|
||||||
|
fen2yuan,
|
||||||
|
formatDateRange,
|
||||||
|
handActitList
|
||||||
|
} from '@/sheep/hooks/useGoods';
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default() {},
|
default () {},
|
||||||
},
|
},
|
||||||
show: {
|
show: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
@ -42,10 +127,10 @@
|
||||||
});
|
});
|
||||||
const emits = defineEmits(['close']);
|
const emits = defineEmits(['close']);
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
activityInfo: computed(() => props.modelValue),
|
activityInfo: computed(() => props.modelValue.activityInfo),
|
||||||
activityMap: {}
|
activityMap: {},
|
||||||
|
couponInfo: computed(() => props.modelValue.couponInfo)
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.show,
|
() => props.show,
|
||||||
() => {
|
() => {
|
||||||
|
@ -56,12 +141,16 @@
|
||||||
if (res.code !== 0) {
|
if (res.code !== 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state.activityMap[activity.id] = res.data;
|
state.activityMap[activity.id] = handActitList(res.data.rules);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
// 领取优惠劵
|
||||||
|
const getBuy = (id) => {
|
||||||
|
emits('get', id);
|
||||||
|
};
|
||||||
|
|
||||||
function onGoodsList(e) {
|
function onGoodsList(e) {
|
||||||
sheep.$router.go('/pages/activity/index', {
|
sheep.$router.go('/pages/activity/index', {
|
||||||
|
@ -72,34 +161,141 @@
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.model-box {
|
.model-box {
|
||||||
height: 60vh;
|
height: 60vh;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
justify-content: center;
|
||||||
font-size: 36rpx;
|
font-size: 36rpx;
|
||||||
height: 80rpx;
|
height: 80rpx;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #333333;
|
color: #333333;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.model-content {
|
.model-content {
|
||||||
|
height: fit-content;
|
||||||
|
max-height: 350rpx;
|
||||||
padding: 0 20rpx;
|
padding: 0 20rpx;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
|
||||||
.model-content-tag {
|
.model-content-tag {
|
||||||
background: rgba(#ff6911, 0.1);
|
// background: rgba(#ff6911, 0.1);
|
||||||
font-size: 24rpx;
|
font-size: 35rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #ff6911;
|
color: #ff6911;
|
||||||
line-height: 42rpx;
|
line-height: 150rpx;
|
||||||
width: 68rpx;
|
width: 200rpx;
|
||||||
height: 32rpx;
|
height: 150rpx;
|
||||||
border-radius: 5rpx;
|
text-align: center;
|
||||||
|
|
||||||
|
// border-radius: 5rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.model-content-title {
|
.model-content-title {
|
||||||
|
width: 450rpx;
|
||||||
|
height: 150rpx;
|
||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #333333;
|
color: #333333;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cicon-forward {
|
.cicon-forward {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
color: #999999;
|
color: #999999;
|
||||||
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
// 新增的
|
||||||
|
.titleLi {
|
||||||
|
margin: 10rpx 0 10rpx 20rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actBox {
|
||||||
|
width: 700rpx;
|
||||||
|
height: 150rpx;
|
||||||
|
background-color: #fff2f2;
|
||||||
|
margin: 10rpx auto;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxCont {
|
||||||
|
width: 700rpx;
|
||||||
|
height: 150rpx;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contBu {
|
||||||
|
height: 80rpx;
|
||||||
|
line-height: 80rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 30rpx;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
-o-text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cotBu-txt {
|
||||||
|
height: 70rpx;
|
||||||
|
line-height: 70rpx;
|
||||||
|
font-size: 25rpx;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.model-content-tag2 {
|
||||||
|
font-size: 35rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #ff6911;
|
||||||
|
width: 200rpx;
|
||||||
|
height: 150rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.usePrice {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 90rpx;
|
||||||
|
line-height: 100rpx;
|
||||||
|
// background-color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.impose {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 50rpx;
|
||||||
|
// line-height: 75rpx;
|
||||||
|
font-size: 23rpx;
|
||||||
|
// background-color: gold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.model-content-title2 {
|
||||||
|
width: 330rpx;
|
||||||
|
height: 150rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333333;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coupon {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 50rpx;
|
||||||
|
line-height: 50rpx;
|
||||||
|
background-color: rgb(255, 68, 68);
|
||||||
|
color: white;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 25rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coupon2 {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 50rpx;
|
||||||
|
line-height: 50rpx;
|
||||||
|
background-color: rgb(203, 192, 191);
|
||||||
|
color: white;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 25rpx;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,23 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<su-popup
|
<su-popup :show="show" type="bottom" round="20" @close="emits('close')" showClose backgroundColor="#f2f2f2">
|
||||||
:show="show"
|
|
||||||
type="bottom"
|
|
||||||
round="20"
|
|
||||||
@close="emits('close')"
|
|
||||||
showClose
|
|
||||||
backgroundColor="#f2f2f2"
|
|
||||||
>
|
|
||||||
<view class="model-box">
|
<view class="model-box">
|
||||||
<view class="title ss-m-t-38 ss-m-l-20 ss-m-b-40">活动优惠</view>
|
<view class="title ss-m-t-38 ss-m-l-20 ss-m-b-40">活动优惠</view>
|
||||||
<scroll-view
|
<scroll-view class="model-content ss-m-l-20" scroll-y :scroll-with-animation="false"
|
||||||
class="model-content ss-m-l-20"
|
:enable-back-to-top="true">
|
||||||
scroll-y
|
<view v-for="(item, index) in state.orderInfo.promotions" :key="index">
|
||||||
:scroll-with-animation="false"
|
|
||||||
:enable-back-to-top="true"
|
|
||||||
>
|
|
||||||
<view v-for="(item, index) in state.orderInfo.promo_infos" :key="index">
|
|
||||||
<view class="ss-flex ss-m-b-40 subtitle">
|
<view class="ss-flex ss-m-b-40 subtitle">
|
||||||
<view>共{{ item.goods_ids.length }}件,</view>
|
<!-- <view>共{{ item.goods_ids.length }}件,</view>
|
||||||
<view v-if="item.activity_type === 'full_discount'">
|
<view v-if="item.activity_type === 'full_discount'">
|
||||||
满{{ item.discount_rule.full }}打{{ item.discount_rule.discount }}折,已减
|
满{{ item.discount_rule.full }}打{{ item.discount_rule.discount }}折,已减
|
||||||
</view>
|
</view>
|
||||||
|
@ -25,15 +14,11 @@
|
||||||
<view v-if="item.activity_type === 'full_reduce'">
|
<view v-if="item.activity_type === 'full_reduce'">
|
||||||
满{{ item.discount_rule.full }}减{{ item.discount_rule.discount }},已减
|
满{{ item.discount_rule.full }}减{{ item.discount_rule.discount }},已减
|
||||||
</view>
|
</view>
|
||||||
<view class="price-text">¥{{ item.promo_discount_money || '0.00' }}</view>
|
<view class="price-text">¥{{ item.promo_discount_money || '0.00' }}</view> -->
|
||||||
</view>
|
<view>
|
||||||
<scroll-view class="scroll-box" scroll-x scroll-anchoring>
|
{{item.description}}
|
||||||
<view class="ss-flex">
|
|
||||||
<view v-for="i in item.goods_ids" :key="i">
|
|
||||||
<image class="content-img" :src="sheep.$url.cdn(getGoodsImg(i))" />
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
|
@ -43,8 +28,14 @@
|
||||||
</su-popup>
|
</su-popup>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, reactive } from 'vue';
|
import {
|
||||||
|
computed,
|
||||||
|
reactive
|
||||||
|
} from 'vue';
|
||||||
import sheep from '@/sheep';
|
import sheep from '@/sheep';
|
||||||
|
import {
|
||||||
|
fen2yuan
|
||||||
|
} from '@/sheep/hooks/useGoods';
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
promoInfo: {
|
promoInfo: {
|
||||||
type: Array,
|
type: Array,
|
||||||
|
@ -56,7 +47,7 @@
|
||||||
},
|
},
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default() {},
|
default () {},
|
||||||
},
|
},
|
||||||
show: {
|
show: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
@ -67,28 +58,31 @@
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
orderInfo: computed(() => props.modelValue),
|
orderInfo: computed(() => props.modelValue),
|
||||||
});
|
});
|
||||||
const getGoodsImg = (e) => {
|
// const getGoodsImg = (e) => {
|
||||||
let goodsImg = '';
|
// let goodsImg = '';
|
||||||
state.orderInfo.goods_list.forEach((i) => {
|
// state.orderInfo.goods_list.forEach((i) => {
|
||||||
if (e == i.goods_id) {
|
// if (e == i.goods_id) {
|
||||||
goodsImg = i.goods.image;
|
// goodsImg = i.goods.image;
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
return goodsImg;
|
// return goodsImg;
|
||||||
};
|
// };
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.model-box {
|
.model-box {
|
||||||
height: 60vh;
|
height: 60vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.model-content {
|
.model-content {
|
||||||
height: 54vh;
|
height: 54vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-footer {
|
.modal-footer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 120rpx;
|
height: 120rpx;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.confirm-btn {
|
.confirm-btn {
|
||||||
width: 710rpx;
|
width: 710rpx;
|
||||||
margin-left: 20rpx;
|
margin-left: 20rpx;
|
||||||
|
@ -97,18 +91,21 @@
|
||||||
border-radius: 40rpx;
|
border-radius: 40rpx;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-img {
|
.content-img {
|
||||||
width: 140rpx;
|
width: 140rpx;
|
||||||
height: 140rpx;
|
height: 140rpx;
|
||||||
margin-right: 20rpx;
|
margin-right: 20rpx;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.subtitle {
|
.subtitle {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #333333;
|
color: #333333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.price-text {
|
.price-text {
|
||||||
color: #ff3000;
|
color: #ff3000;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
|
@ -135,7 +135,7 @@
|
||||||
/**
|
/**
|
||||||
* 商品卡片
|
* 商品卡片
|
||||||
*/
|
*/
|
||||||
import { computed, reactive, onMounted } from 'vue';
|
import { computed, reactive, onMounted, ref } from 'vue';
|
||||||
import sheep from '@/sheep';
|
import sheep from '@/sheep';
|
||||||
import SpuApi from '@/sheep/api/product/spu';
|
import SpuApi from '@/sheep/api/product/spu';
|
||||||
|
|
||||||
|
@ -227,10 +227,61 @@
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//获取结算信息
|
||||||
|
const settleData = ref()
|
||||||
|
async function getSettlementByIds(ids) {
|
||||||
|
const { data } = await SpuApi.getSettlementProduct(ids);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
//计算展示价格的函数
|
||||||
|
async function enrichDataWithSkus(data, array) {
|
||||||
|
// 创建一个映射,以 id 为键,存储 data 数组中的对象
|
||||||
|
const dataMap = new Map(data.map(item => [item.id, { ...item }]));
|
||||||
|
|
||||||
|
// 遍历 array 数组
|
||||||
|
array.forEach(item => {
|
||||||
|
// 初始化 discountPrice 和 vipPrice 为 null
|
||||||
|
let discountPrice = null;
|
||||||
|
let vipPrice = null;
|
||||||
|
let foundType4 = false;
|
||||||
|
let foundType6 = false;
|
||||||
|
|
||||||
|
// 遍历 skus 数组,寻找 type 为 4 和 6 的首个条目
|
||||||
|
item.skus.forEach(sku => {
|
||||||
|
if (!foundType4 && sku.type === 4) {
|
||||||
|
discountPrice = sku.price;
|
||||||
|
foundType4 = true;
|
||||||
|
}
|
||||||
|
if (!foundType6 && sku.type === 6) {
|
||||||
|
vipPrice = sku.price;
|
||||||
|
foundType6 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果已经找到 type 为 4 和 6 的条目,则不需要继续遍历
|
||||||
|
if (foundType4 && foundType6) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新 dataMap 中对应的对象
|
||||||
|
if (dataMap.has(item.id)) {
|
||||||
|
dataMap.get(item.id).discountPrice = discountPrice;
|
||||||
|
dataMap.get(item.id).vipPrice = vipPrice;
|
||||||
|
dataMap.get(item.id).reward = item.reward;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 返回更新后的数据数组
|
||||||
|
return Array.from(dataMap.values());
|
||||||
|
}
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 加载商品列表
|
// 加载商品列表
|
||||||
state.goodsList = await getGoodsListByIds(spuIds.join(','));
|
const ms = await getGoodsListByIds(spuIds.join(','));
|
||||||
|
settleData.value = await getSettlementByIds(spuIds.join(','))
|
||||||
|
state.goodsList = await enrichDataWithSkus(ms,settleData.value)
|
||||||
// 只有双列布局时需要
|
// 只有双列布局时需要
|
||||||
if (layoutType === LayoutTypeEnum.TWO_COL){
|
if (layoutType === LayoutTypeEnum.TWO_COL){
|
||||||
// 分列
|
// 分列
|
||||||
|
|
|
@ -2,38 +2,29 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="ss-goods-wrap">
|
<view class="ss-goods-wrap">
|
||||||
<!-- xs卡片:横向紧凑型,一行放两个,图片左内容右边 -->
|
<!-- xs卡片:横向紧凑型,一行放两个,图片左内容右边 -->
|
||||||
<view
|
<view v-if="size === 'xs'" class="xs-goods-card ss-flex ss-col-stretch" :style="[elStyles]" @tap="onClick">
|
||||||
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
|
<image class="xs-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFit"></image>
|
||||||
class="xs-img-box"
|
<view v-if="goodsFields.title?.show || goodsFields.name?.show || goodsFields.price?.show"
|
||||||
:src="sheep.$url.cdn(data.image || data.picUrl)"
|
class="xs-goods-content ss-flex-col ss-row-around">
|
||||||
mode="aspectFit"
|
<view v-if="goodsFields.title?.show || goodsFields.name?.show" class="xs-goods-title ss-line-1"
|
||||||
></image>
|
:style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]">
|
||||||
<view
|
|
||||||
v-if="goodsFields.title?.show || goodsFields.name?.show || goodsFields.price?.show"
|
|
||||||
class="xs-goods-content ss-flex-col ss-row-around"
|
|
||||||
>
|
|
||||||
<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
|
<!-- 这里是新加的会员价和限时优惠 -->
|
||||||
v-if="goodsFields.price?.show"
|
<view class="iconBox" v-if="data.discountPrice || data.vipPrice || data.reward">
|
||||||
class="xs-goods-price font-OPPOSANS"
|
<view class="card" v-if="iconShow">{{iconShow}}</view>
|
||||||
:style="[{ color: goodsFields.price.color }]"
|
<view class="card2" v-if="data.reward">{{data.reward.rewardActivity}}</view>
|
||||||
>
|
</view>
|
||||||
|
<!-- 这里是新加的会员价和限时优惠结束 -->
|
||||||
|
<view 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>
|
||||||
{{ 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>
|
||||||
|
@ -43,30 +34,26 @@
|
||||||
<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
|
<image class="sm-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFill"></image>
|
||||||
class="sm-img-box"
|
|
||||||
:src="sheep.$url.cdn(data.image || data.picUrl)"
|
|
||||||
mode="aspectFill"
|
|
||||||
></image>
|
|
||||||
|
|
||||||
<view
|
<view v-if="goodsFields.title?.show || goodsFields.name?.show || goodsFields.price?.show"
|
||||||
v-if="goodsFields.title?.show || goodsFields.name?.show || goodsFields.price?.show"
|
class="sm-goods-content" :style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]">
|
||||||
class="sm-goods-content"
|
<view v-if="goodsFields.title?.show || goodsFields.name?.show"
|
||||||
:style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]"
|
class="sm-goods-title ss-line-1 ss-m-b-16">
|
||||||
>
|
|
||||||
<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
|
<!-- 这里是新加的会员价和限时优惠 -->
|
||||||
v-if="goodsFields.price?.show"
|
<view class="iconBox" v-if="data.discountPrice || data.vipPrice || data.reward">
|
||||||
class="sm-goods-price font-OPPOSANS"
|
<view class="card" v-if="iconShow">{{iconShow}}</view>
|
||||||
:style="[{ color: goodsFields.price.color }]"
|
<view class="card2" v-if="data.reward">{{data.reward.rewardActivity}}</view>
|
||||||
>
|
</view>
|
||||||
|
<!-- 这里是新加的会员价和限时优惠结束 -->
|
||||||
|
<view 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>
|
||||||
{{ 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>
|
||||||
|
@ -76,58 +63,43 @@
|
||||||
<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
|
<image class="md-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="widthFix"></image>
|
||||||
class="md-img-box"
|
<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">
|
||||||
:src="sheep.$url.cdn(data.image || data.picUrl)"
|
<view v-if="goodsFields.title?.show || goodsFields.name?.show" class="md-goods-title ss-line-1"
|
||||||
mode="widthFix"
|
:style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]">
|
||||||
></image>
|
|
||||||
<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
|
|
||||||
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
|
<view v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show"
|
||||||
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
|
<view class="activity-tag ss-m-r-10 ss-m-t-16" v-for="item in data.promos" :key="item.id">
|
||||||
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>
|
||||||
</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.rewardActivity}}</view>
|
||||||
|
</view>
|
||||||
|
<!-- 这里是新加的会员价和限时优惠结束 -->
|
||||||
<view class="ss-flex ss-col-bottom">
|
<view class="ss-flex ss-col-bottom">
|
||||||
<view
|
<view v-if="goodsFields.price?.show" class="md-goods-price ss-m-t-16 font-OPPOSANS ss-m-r-10"
|
||||||
v-if="goodsFields.price?.show"
|
:style="[{ color: goodsFields.price.color }]">
|
||||||
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>
|
||||||
{{ 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="
|
|
||||||
(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>
|
||||||
|
@ -146,12 +118,7 @@
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- lg卡片:横向型,一行放一个,图片左内容右边 -->
|
<!-- lg卡片:横向型,一行放一个,图片左内容右边 -->
|
||||||
<view
|
<view v-if="size === 'lg'" class="lg-goods-card ss-flex ss-col-stretch" :style="[elStyles]" @tap="onClick">
|
||||||
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>
|
||||||
|
@ -159,25 +126,16 @@
|
||||||
<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
|
<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"
|
|
||||||
></image>
|
|
||||||
<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
|
<view v-if="goodsFields.title?.show || goodsFields.name?.show" class="lg-goods-title ss-line-2"
|
||||||
v-if="goodsFields.title?.show || goodsFields.name?.show"
|
:style="[{ color: titleColor }]">
|
||||||
class="lg-goods-title ss-line-2"
|
|
||||||
:style="[{ color: titleColor }]"
|
|
||||||
>
|
|
||||||
{{ data.title || data.name }}
|
{{ data.title || data.name }}
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show"
|
||||||
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>
|
||||||
|
@ -189,25 +147,27 @@
|
||||||
</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.rewardActivity}}</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"
|
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
|
<view v-if="
|
||||||
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>
|
||||||
<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">
|
||||||
|
@ -227,54 +187,45 @@
|
||||||
<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
|
<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"
|
|
||||||
></image>
|
|
||||||
|
|
||||||
<view class="sl-goods-content">
|
<view class="sl-goods-content">
|
||||||
<view>
|
<view>
|
||||||
<view
|
<view v-if="goodsFields.title?.show || goodsFields.name?.show" class="sl-goods-title ss-line-1"
|
||||||
v-if="goodsFields.title?.show || goodsFields.name?.show"
|
:style="[{ color: titleColor }]">
|
||||||
class="sl-goods-title ss-line-1"
|
|
||||||
:style="[{ color: titleColor }]"
|
|
||||||
>
|
|
||||||
{{ data.title || data.name }}
|
{{ data.title || data.name }}
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show"
|
||||||
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
|
<view class="activity-tag ss-m-r-10 ss-m-t-16" v-for="item in data.promos" :key="item.id">
|
||||||
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>
|
||||||
</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.rewardActivity}}</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="
|
|
||||||
(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>
|
||||||
|
@ -285,9 +236,9 @@
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<slot name="cart"
|
<slot name="cart">
|
||||||
><view class="buy-box ss-flex ss-col-center ss-row-center">去购买</view></slot
|
<view class="buy-box ss-flex ss-col-center ss-row-center">去购买</view>
|
||||||
>
|
</slot>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
@ -321,13 +272,26 @@
|
||||||
* @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 {
|
||||||
import { formatStock } from '@/sheep/hooks/useGoods';
|
fen2yuan,
|
||||||
|
formatSales
|
||||||
|
} from '@/sheep/hooks/useGoods';
|
||||||
|
import {
|
||||||
|
formatStock
|
||||||
|
} from '@/sheep/hooks/useGoods';
|
||||||
import goodsCollectVue from '@/pages/user/goods-collect.vue';
|
import goodsCollectVue from '@/pages/user/goods-collect.vue';
|
||||||
import { isArray } from 'lodash-es';
|
import {
|
||||||
|
isArray
|
||||||
|
} from 'lodash-es';
|
||||||
// 数据
|
// 数据
|
||||||
const state = reactive({});
|
const state = reactive({});
|
||||||
|
|
||||||
|
@ -335,20 +299,32 @@
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
goodsFields: {
|
goodsFields: {
|
||||||
type: [Array, Object],
|
type: [Array, Object],
|
||||||
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
|
||||||
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -417,7 +393,25 @@
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
//判断限时优惠和会员价标签内容暂时导致页面出错,又舍不得丢,等着把新的数据整合到商品信息中,也用起来
|
||||||
|
const iconShow = handle()
|
||||||
|
|
||||||
|
function handle() {
|
||||||
|
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 {
|
||||||
|
@ -449,12 +443,18 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
// 获取卡片实时高度
|
// 获取卡片实时高度
|
||||||
const { proxy } = getCurrentInstance();
|
const {
|
||||||
|
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() {
|
||||||
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];
|
||||||
|
@ -482,11 +482,13 @@
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
|
||||||
.tag-icon {
|
.tag-icon {
|
||||||
width: 72rpx;
|
width: 72rpx;
|
||||||
height: 44rpx;
|
height: 44rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.seckill-tag {
|
.seckill-tag {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -501,6 +503,7 @@
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
line-height: 32rpx;
|
line-height: 32rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.groupon-tag {
|
.groupon-tag {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -515,14 +518,17 @@
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
line-height: 32rpx;
|
line-height: 32rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.goods-img {
|
.goods-img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.price-unit {
|
.price-unit {
|
||||||
margin-right: -4px;
|
margin-right: -4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sales-text {
|
.sales-text {
|
||||||
display: table;
|
display: table;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
|
@ -586,10 +592,12 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 208rpx;
|
height: 208rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sm-goods-content {
|
.sm-goods-content {
|
||||||
padding: 20rpx 16rpx;
|
padding: 20rpx 16rpx;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sm-goods-title {
|
.sm-goods-title {
|
||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
color: #333;
|
color: #333;
|
||||||
|
@ -619,6 +627,7 @@
|
||||||
color: #333;
|
color: #333;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.md-goods-subtitle {
|
.md-goods-subtitle {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
@ -669,6 +678,7 @@
|
||||||
// line-height: 36rpx;
|
// line-height: 36rpx;
|
||||||
// width: 410rpx;
|
// width: 410rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lg-goods-subtitle {
|
.lg-goods-subtitle {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
@ -695,6 +705,7 @@
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag-box {
|
.tag-box {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -708,10 +719,12 @@
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: $white;
|
background-color: $white;
|
||||||
|
|
||||||
.sl-goods-content {
|
.sl-goods-content {
|
||||||
padding: 20rpx 20rpx;
|
padding: 20rpx 20rpx;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sl-img-box {
|
.sl-img-box {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 360rpx;
|
height: 360rpx;
|
||||||
|
@ -722,6 +735,7 @@
|
||||||
color: #333;
|
color: #333;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sl-goods-subtitle {
|
.sl-goods-subtitle {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
@ -748,4 +762,31 @@
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
.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>
|
|
@ -1,34 +1,38 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- 规格弹窗 -->
|
<!-- 规格弹窗 -->
|
||||||
<su-popup :show="show" round="10" @close="emits('close')">
|
<su-popup :show="show" round="10" @close="emits('close')">
|
||||||
<!-- SKU 信息 -->
|
<!-- SKU 信息 -->
|
||||||
<view class="ss-modal-box bg-white ss-flex-col">
|
<view class="ss-modal-box bg-white ss-flex-col">
|
||||||
<view class="modal-header ss-flex ss-col-center">
|
<view class="modal-header ss-flex ss-col-center">
|
||||||
<view class="header-left ss-m-r-30">
|
<view class="header-left ss-m-r-30">
|
||||||
<image class="sku-image" :src="state.selectedSku.picUrl || goodsInfo.picUrl" mode="aspectFill" />
|
<image class="sku-image" :src="state.selectedSku.picUrl || goodsInfo.picUrl" mode="aspectFill" />
|
||||||
</view>
|
</view>
|
||||||
<view class="header-right ss-flex-col ss-row-between ss-flex-1">
|
<view class="header-right ss-flex-col ss-row-between ss-flex-1">
|
||||||
<view class="goods-title ss-line-2">{{ goodsInfo.name }}</view>
|
<view class="goods-title ss-line-2">{{ goodsInfo.name }}</view>
|
||||||
<view class="header-right-bottom ss-flex ss-col-center ss-row-between">
|
<view class="header-right-bottom ss-flex ss-col-center ss-row-between">
|
||||||
<view class="ss-flex">
|
<view class="ss-flex">
|
||||||
<view class="price-text">
|
<view class="price-text">
|
||||||
{{ fen2yuan( state.selectedSku.price || goodsInfo.price) }}
|
{{ fen2yuan( state.selectedSku.price || goodsInfo.price) }}
|
||||||
</view>
|
<text v-if="state.selectedSku.type == 6"><text class="iconBox">会员价</text><text
|
||||||
</view>
|
class="origin-price-text">{{fen2yuan(state.selectedSku.oldPrice)}}</text></text>
|
||||||
<view class="stock-text ss-m-l-20">
|
<text v-if="state.selectedSku.type == 4"><text class="iconBox">限时优惠</text><text
|
||||||
{{ formatStock('exact', state.selectedSku.stock || goodsInfo.stock) }}
|
class="origin-price-text">{{fen2yuan(state.selectedSku.oldPrice)}}</text></text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
<view class="stock-text ss-m-l-20">
|
||||||
</view>
|
{{ formatStock('exact', state.selectedSku.stock || goodsInfo.stock) }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- 属性选择 -->
|
<!-- 属性选择 -->
|
||||||
<view class="modal-content ss-flex-1">
|
<view class="modal-content ss-flex-1">
|
||||||
<scroll-view scroll-y="true" class="modal-content-scroll" @touchmove.stop>
|
<scroll-view scroll-y="true" class="modal-content-scroll" @touchmove.stop>
|
||||||
<view class="sku-item ss-m-b-20" v-for="property in propertyList" :key="property.id">
|
<view class="sku-item ss-m-b-20" v-for="property in propertyList" :key="property.id">
|
||||||
<view class="label-text ss-m-b-20">{{ property.name }}</view>
|
<view class="label-text ss-m-b-20">{{ property.name }}</view>
|
||||||
<view class="ss-flex ss-col-center ss-flex-wrap">
|
<view class="ss-flex ss-col-center ss-flex-wrap">
|
||||||
<button class="ss-reset-button spec-btn" v-for="value in property.values" :class="[
|
<button class="ss-reset-button spec-btn" v-for="value in property.values" :class="[
|
||||||
{
|
{
|
||||||
'ui-BG-Main-Gradient': state.currentPropertyArray[property.id] === value.id,
|
'ui-BG-Main-Gradient': state.currentPropertyArray[property.id] === value.id,
|
||||||
},
|
},
|
||||||
|
@ -36,71 +40,78 @@
|
||||||
'disabled-btn': value.disabled === true,
|
'disabled-btn': value.disabled === true,
|
||||||
},
|
},
|
||||||
]" :key="value.id" :disabled="value.disabled === true" @tap="onSelectSku(property.id, value.id)">
|
]" :key="value.id" :disabled="value.disabled === true" @tap="onSelectSku(property.id, value.id)">
|
||||||
{{ value.name }}
|
{{ value.name }}
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="buy-num-box ss-flex ss-col-center ss-row-between ss-m-b-40">
|
<view class="buy-num-box ss-flex ss-col-center ss-row-between ss-m-b-40">
|
||||||
<view class="label-text">购买数量</view>
|
<view class="label-text">购买数量</view>
|
||||||
<su-number-box :min="1" :max="state.selectedSku.stock" :step="1"
|
<su-number-box :min="1" :max="state.selectedSku.stock" :step="1"
|
||||||
v-model="state.selectedSku.goods_num" @change="onNumberChange($event)" />
|
v-model="state.selectedSku.goods_num" @change="onNumberChange($event)" />
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 操作区 -->
|
<!-- 操作区 -->
|
||||||
<view class="modal-footer border-top">
|
<view class="modal-footer border-top">
|
||||||
<view class="buy-box ss-flex ss-col-center ss-flex ss-col-center ss-row-center">
|
<view class="buy-box ss-flex ss-col-center ss-flex ss-col-center ss-row-center">
|
||||||
<button class="ss-reset-button add-btn ui-Shadow-Main" @tap="onAddCart">加入购物车</button>
|
<button class="ss-reset-button add-btn ui-Shadow-Main" @tap="onAddCart">加入购物车</button>
|
||||||
<button class="ss-reset-button buy-btn ui-Shadow-Main" @tap="onBuy">立即购买</button>
|
<button class="ss-reset-button buy-btn ui-Shadow-Main" @tap="onBuy">立即购买</button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</su-popup>
|
</su-popup>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, reactive, watch } from 'vue';
|
import {
|
||||||
import sheep from '@/sheep';
|
computed,
|
||||||
import { formatStock, convertProductPropertyList, fen2yuan } from '@/sheep/hooks/useGoods';
|
reactive,
|
||||||
|
watch
|
||||||
|
} from 'vue';
|
||||||
|
import sheep from '@/sheep';
|
||||||
|
import {
|
||||||
|
formatStock,
|
||||||
|
convertProductPropertyList,
|
||||||
|
fen2yuan
|
||||||
|
} from '@/sheep/hooks/useGoods';
|
||||||
|
|
||||||
const emits = defineEmits(['change', 'addCart', 'buy', 'close']);
|
const emits = defineEmits(['change', 'addCart', 'buy', 'close']);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
goodsInfo: {
|
goodsInfo: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default () {},
|
default () {},
|
||||||
},
|
},
|
||||||
show: {
|
show: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
selectedSku: {}, // 选中的 SKU
|
selectedSku: {}, // 选中的 SKU
|
||||||
currentPropertyArray: [], // 当前选中的属性,实际是个 Map。key 是 property 编号,value 是 value 编号
|
currentPropertyArray: [], // 当前选中的属性,实际是个 Map。key 是 property 编号,value 是 value 编号
|
||||||
});
|
});
|
||||||
|
|
||||||
const propertyList = convertProductPropertyList(props.goodsInfo.skus);
|
const propertyList = convertProductPropertyList(props.goodsInfo.skus);
|
||||||
|
// SKU 列表
|
||||||
// SKU 列表
|
const skuList = computed(() => {
|
||||||
const skuList = computed(() => {
|
let skuPrices = props.goodsInfo.skus;
|
||||||
let skuPrices = props.goodsInfo.skus;
|
|
||||||
for (let price of skuPrices) {
|
for (let price of skuPrices) {
|
||||||
price.value_id_array = price.properties.map((item) => item.valueId)
|
price.value_id_array = price.properties.map((item) => item.valueId)
|
||||||
}
|
}
|
||||||
return skuPrices;
|
return skuPrices;
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => state.selectedSku,
|
() => state.selectedSku,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
emits('change', newVal);
|
emits('change', newVal);
|
||||||
}, {
|
}, {
|
||||||
immediate: true, // 立即执行
|
immediate: true, // 立即执行
|
||||||
deep: true, // 深度监听
|
deep: true, // 深度监听
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// 输入框改变数量
|
// 输入框改变数量
|
||||||
function onNumberChange(e) {
|
function onNumberChange(e) {
|
||||||
|
@ -110,21 +121,21 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加入购物车
|
// 加入购物车
|
||||||
function onAddCart() {
|
function onAddCart() {
|
||||||
if (state.selectedSku.id <= 0) {
|
if (state.selectedSku.id <= 0) {
|
||||||
sheep.$helper.toast('请选择规格');
|
sheep.$helper.toast('请选择规格');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (state.selectedSku.stock <= 0) {
|
if (state.selectedSku.stock <= 0) {
|
||||||
sheep.$helper.toast('库存不足');
|
sheep.$helper.toast('库存不足');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
emits('addCart', state.selectedSku);
|
emits('addCart', state.selectedSku);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 立即购买
|
// 立即购买
|
||||||
function onBuy() {
|
function onBuy() {
|
||||||
if (state.selectedSku.id <= 0) {
|
if (state.selectedSku.id <= 0) {
|
||||||
sheep.$helper.toast('请选择规格');
|
sheep.$helper.toast('请选择规格');
|
||||||
return;
|
return;
|
||||||
|
@ -134,273 +145,296 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emits('buy', state.selectedSku);
|
emits('buy', state.selectedSku);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 改变禁用状态:计算每个 property 属性值的按钮,是否禁用
|
// 改变禁用状态:计算每个 property 属性值的按钮,是否禁用
|
||||||
function changeDisabled(isChecked = false, propertyId = 0, valueId = 0) {
|
function changeDisabled(isChecked = false, propertyId = 0, valueId = 0) {
|
||||||
let newSkus = []; // 所有可以选择的 sku 数组
|
let newSkus = []; // 所有可以选择的 sku 数组
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
// 情况一:选中 property
|
// 情况一:选中 property
|
||||||
// 获得当前点击选中 property 的、所有可用 SKU
|
// 获得当前点击选中 property 的、所有可用 SKU
|
||||||
for (let price of skuList.value) {
|
for (let price of skuList.value) {
|
||||||
if (price.stock <= 0) {
|
if (price.stock <= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (price.value_id_array.indexOf(valueId) >= 0) {
|
if (price.value_id_array.indexOf(valueId) >= 0) {
|
||||||
newSkus.push(price);
|
newSkus.push(price);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 情况二:取消选中 property
|
// 情况二:取消选中 property
|
||||||
// 当前所选 property 下,所有可以选择的 SKU
|
// 当前所选 property 下,所有可以选择的 SKU
|
||||||
newSkus = getCanUseSkuList();
|
newSkus = getCanUseSkuList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 所有存在并且有库存未选择的 SKU 的 value 属性值 id
|
// 所有存在并且有库存未选择的 SKU 的 value 属性值 id
|
||||||
let noChooseValueIds = [];
|
let noChooseValueIds = [];
|
||||||
for (let price of newSkus) {
|
for (let price of newSkus) {
|
||||||
noChooseValueIds = noChooseValueIds.concat(price.value_id_array);
|
noChooseValueIds = noChooseValueIds.concat(price.value_id_array);
|
||||||
}
|
}
|
||||||
noChooseValueIds = Array.from(new Set(noChooseValueIds)); // 去重
|
noChooseValueIds = Array.from(new Set(noChooseValueIds)); // 去重
|
||||||
|
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
// 去除当前选中的 value 属性值 id
|
// 去除当前选中的 value 属性值 id
|
||||||
let index = noChooseValueIds.indexOf(valueId);
|
let index = noChooseValueIds.indexOf(valueId);
|
||||||
noChooseValueIds.splice(index, 1);
|
noChooseValueIds.splice(index, 1);
|
||||||
} else {
|
} else {
|
||||||
// 循环去除当前已选择的 value 属性值 id
|
// 循环去除当前已选择的 value 属性值 id
|
||||||
state.currentPropertyArray.forEach((currentPropertyId) => {
|
state.currentPropertyArray.forEach((currentPropertyId) => {
|
||||||
if (currentPropertyId.toString() !== '') {
|
if (currentPropertyId.toString() !== '') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// currentPropertyId 为空是反选 填充的
|
// currentPropertyId 为空是反选 填充的
|
||||||
let index = noChooseValueIds.indexOf(currentPropertyId);
|
let index = noChooseValueIds.indexOf(currentPropertyId);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
// currentPropertyId 存在于 noChooseValueIds
|
// currentPropertyId 存在于 noChooseValueIds
|
||||||
noChooseValueIds.splice(index, 1);
|
noChooseValueIds.splice(index, 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当前已选择的 property 数组
|
// 当前已选择的 property 数组
|
||||||
let choosePropertyIds = [];
|
let choosePropertyIds = [];
|
||||||
if (!isChecked) {
|
if (!isChecked) {
|
||||||
// 当前已选择的 property
|
// 当前已选择的 property
|
||||||
state.currentPropertyArray.forEach((currentPropertyId, currentValueId) => {
|
state.currentPropertyArray.forEach((currentPropertyId, currentValueId) => {
|
||||||
if (currentPropertyId !== '') {
|
if (currentPropertyId !== '') {
|
||||||
// currentPropertyId 为空是反选 填充的
|
// currentPropertyId 为空是反选 填充的
|
||||||
choosePropertyIds.push(currentValueId);
|
choosePropertyIds.push(currentValueId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// 当前点击选择的 property
|
// 当前点击选择的 property
|
||||||
choosePropertyIds = [propertyId];
|
choosePropertyIds = [propertyId];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let propertyIndex in propertyList) {
|
for (let propertyIndex in propertyList) {
|
||||||
// 当前点击的 property、或者取消选择时候,已选中的 property 不进行处理
|
// 当前点击的 property、或者取消选择时候,已选中的 property 不进行处理
|
||||||
if (choosePropertyIds.indexOf(propertyList[propertyIndex]['id']) >= 0) {
|
if (choosePropertyIds.indexOf(propertyList[propertyIndex]['id']) >= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 如果当前 property id 不存在于有库存的 SKU 中,则禁用
|
// 如果当前 property id 不存在于有库存的 SKU 中,则禁用
|
||||||
for (let valueIndex in propertyList[propertyIndex]['values']) {
|
for (let valueIndex in propertyList[propertyIndex]['values']) {
|
||||||
propertyList[propertyIndex]['values'][valueIndex]['disabled'] =
|
propertyList[propertyIndex]['values'][valueIndex]['disabled'] =
|
||||||
noChooseValueIds.indexOf(propertyList[propertyIndex]['values'][valueIndex]['id']) < 0; // true 禁用 or false 不禁用
|
noChooseValueIds.indexOf(propertyList[propertyIndex]['values'][valueIndex]['id']) <
|
||||||
}
|
0; // true 禁用 or false 不禁用
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 当前所选属性下,获取所有有库存的 SKU 们
|
// 当前所选属性下,获取所有有库存的 SKU 们
|
||||||
function getCanUseSkuList() {
|
function getCanUseSkuList() {
|
||||||
let newSkus = [];
|
let newSkus = [];
|
||||||
for (let sku of skuList.value) {
|
for (let sku of skuList.value) {
|
||||||
if (sku.stock <= 0) {
|
if (sku.stock <= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let isOk = true;
|
let isOk = true;
|
||||||
state.currentPropertyArray.forEach((propertyId) => {
|
state.currentPropertyArray.forEach((propertyId) => {
|
||||||
// propertyId 不为空,并且,这个 条 sku 没有被选中,则排除
|
// propertyId 不为空,并且,这个 条 sku 没有被选中,则排除
|
||||||
if (propertyId.toString() !== '' && sku.value_id_array.indexOf(propertyId) < 0) {
|
if (propertyId.toString() !== '' && sku.value_id_array.indexOf(propertyId) < 0) {
|
||||||
isOk = false;
|
isOk = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (isOk) {
|
if (isOk) {
|
||||||
newSkus.push(sku);
|
newSkus.push(sku);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newSkus;
|
return newSkus;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选择规格
|
// 选择规格
|
||||||
function onSelectSku(propertyId, valueId) {
|
function onSelectSku(propertyId, valueId) {
|
||||||
// 清空已选择
|
// 清空已选择
|
||||||
let isChecked = true; // 选中 or 取消选中
|
let isChecked = true; // 选中 or 取消选中
|
||||||
if (state.currentPropertyArray[propertyId] !== undefined && state.currentPropertyArray[propertyId] === valueId) {
|
if (state.currentPropertyArray[propertyId] !== undefined && state.currentPropertyArray[propertyId] === valueId) {
|
||||||
// 点击已被选中的,删除并填充 ''
|
// 点击已被选中的,删除并填充 ''
|
||||||
isChecked = false;
|
isChecked = false;
|
||||||
state.currentPropertyArray.splice(propertyId, 1, '');
|
state.currentPropertyArray.splice(propertyId, 1, '');
|
||||||
} else {
|
} else {
|
||||||
// 选中
|
// 选中
|
||||||
state.currentPropertyArray[propertyId] = valueId;
|
state.currentPropertyArray[propertyId] = valueId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选中的 property 大类
|
// 选中的 property 大类
|
||||||
let choosePropertyId = [];
|
let choosePropertyId = [];
|
||||||
state.currentPropertyArray.forEach((currentPropertyId) => {
|
state.currentPropertyArray.forEach((currentPropertyId) => {
|
||||||
if (currentPropertyId !== '') {
|
if (currentPropertyId !== '') {
|
||||||
// currentPropertyId 为空是反选 填充的
|
// currentPropertyId 为空是反选 填充的
|
||||||
choosePropertyId.push(currentPropertyId);
|
choosePropertyId.push(currentPropertyId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 当前所选 property 下,所有可以选择的 SKU 们
|
// 当前所选 property 下,所有可以选择的 SKU 们
|
||||||
let newSkuList = getCanUseSkuList();
|
let newSkuList = getCanUseSkuList();
|
||||||
|
|
||||||
// 判断所有 property 大类是否选择完成
|
// 判断所有 property 大类是否选择完成
|
||||||
if (choosePropertyId.length === propertyList.length && newSkuList.length) {
|
if (choosePropertyId.length === propertyList.length && newSkuList.length) {
|
||||||
newSkuList[0].goods_num = state.selectedSku.goods_num || 1;
|
newSkuList[0].goods_num = state.selectedSku.goods_num || 1;
|
||||||
state.selectedSku = newSkuList[0];
|
state.selectedSku = newSkuList[0];
|
||||||
} else {
|
} else {
|
||||||
state.selectedSku = {};
|
state.selectedSku = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 改变 property 禁用状态
|
// 改变 property 禁用状态
|
||||||
changeDisabled(isChecked, propertyId, valueId);
|
changeDisabled(isChecked, propertyId, valueId);
|
||||||
}
|
}
|
||||||
|
|
||||||
changeDisabled(false);
|
changeDisabled(false);
|
||||||
// TODO 芋艿:待讨论的优化点:1)单规格,要不要默认选中;2)默认要不要选中第一个规格
|
// TODO 芋艿:待讨论的优化点:1)单规格,要不要默认选中;2)默认要不要选中第一个规格
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
// 购买
|
// 购买
|
||||||
.buy-box {
|
.buy-box {
|
||||||
padding: 10rpx 0;
|
padding: 10rpx 0;
|
||||||
|
|
||||||
.add-btn {
|
.add-btn {
|
||||||
width: 356rpx;
|
width: 356rpx;
|
||||||
height: 80rpx;
|
height: 80rpx;
|
||||||
border-radius: 40rpx 0 0 40rpx;
|
border-radius: 40rpx 0 0 40rpx;
|
||||||
background-color: var(--ui-BG-Main-light);
|
background-color: var(--ui-BG-Main-light);
|
||||||
color: var(--ui-BG-Main);
|
color: var(--ui-BG-Main);
|
||||||
}
|
}
|
||||||
|
|
||||||
.buy-btn {
|
.buy-btn {
|
||||||
width: 356rpx;
|
width: 356rpx;
|
||||||
height: 80rpx;
|
height: 80rpx;
|
||||||
border-radius: 0 40rpx 40rpx 0;
|
border-radius: 0 40rpx 40rpx 0;
|
||||||
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
|
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.score-btn {
|
.score-btn {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0 20rpx;
|
margin: 0 20rpx;
|
||||||
height: 80rpx;
|
height: 80rpx;
|
||||||
border-radius: 40rpx;
|
border-radius: 40rpx;
|
||||||
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
|
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ss-modal-box {
|
.ss-modal-box {
|
||||||
border-radius: 30rpx 30rpx 0 0;
|
border-radius: 30rpx 30rpx 0 0;
|
||||||
max-height: 1000rpx;
|
max-height: 1000rpx;
|
||||||
|
|
||||||
.modal-header {
|
.modal-header {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 80rpx 20rpx 40rpx;
|
padding: 80rpx 20rpx 40rpx;
|
||||||
|
|
||||||
.sku-image {
|
.sku-image {
|
||||||
width: 160rpx;
|
width: 160rpx;
|
||||||
height: 160rpx;
|
height: 160rpx;
|
||||||
border-radius: 10rpx;
|
border-radius: 10rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-right {
|
.header-right {
|
||||||
height: 160rpx;
|
height: 160rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.close-icon {
|
.close-icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10rpx;
|
top: 10rpx;
|
||||||
right: 20rpx;
|
right: 20rpx;
|
||||||
font-size: 46rpx;
|
font-size: 46rpx;
|
||||||
opacity: 0.2;
|
opacity: 0.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.goods-title {
|
.goods-title {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 42rpx;
|
line-height: 42rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.score-img {
|
.score-img {
|
||||||
width: 36rpx;
|
width: 36rpx;
|
||||||
height: 36rpx;
|
height: 36rpx;
|
||||||
margin: 0 4rpx;
|
margin: 0 4rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.score-text {
|
.score-text {
|
||||||
font-size: 30rpx;
|
font-size: 30rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: $red;
|
color: $red;
|
||||||
font-family: OPPOSANS;
|
font-family: OPPOSANS;
|
||||||
}
|
}
|
||||||
|
|
||||||
.price-text {
|
.price-text {
|
||||||
font-size: 30rpx;
|
font-size: 30rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: $red;
|
color: $red;
|
||||||
font-family: OPPOSANS;
|
font-family: OPPOSANS;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
content: '¥';
|
content: '¥';
|
||||||
font-size: 30rpx;
|
font-size: 30rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: $red;
|
color: $red;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.stock-text {
|
.stock-text {
|
||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
color: #999999;
|
color: #999999;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-content {
|
.modal-content {
|
||||||
padding: 0 20rpx;
|
padding: 0 20rpx;
|
||||||
|
|
||||||
.modal-content-scroll {
|
.modal-content-scroll {
|
||||||
max-height: 600rpx;
|
max-height: 600rpx;
|
||||||
|
|
||||||
.label-text {
|
.label-text {
|
||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.buy-num-box {
|
.buy-num-box {
|
||||||
height: 100rpx;
|
height: 100rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spec-btn {
|
.spec-btn {
|
||||||
height: 60rpx;
|
height: 60rpx;
|
||||||
min-width: 100rpx;
|
min-width: 100rpx;
|
||||||
padding: 0 30rpx;
|
padding: 0 30rpx;
|
||||||
background: #f4f4f4;
|
background: #f4f4f4;
|
||||||
border-radius: 30rpx;
|
border-radius: 30rpx;
|
||||||
color: #434343;
|
color: #434343;
|
||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
margin-right: 10rpx;
|
margin-right: 10rpx;
|
||||||
margin-bottom: 10rpx;
|
margin-bottom: 10rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.disabled-btn {
|
.disabled-btn {
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
color: #c6c6c6;
|
color: #c6c6c6;
|
||||||
background: #f8f8f8;
|
background: #f8f8f8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.iconBox {
|
||||||
|
width: fit-content;
|
||||||
|
height: fit-content;
|
||||||
|
padding: 2rpx 10rpx;
|
||||||
|
background-color: rgb(255, 242, 241);
|
||||||
|
color: #ff2621;
|
||||||
|
font-size: 24rpx;
|
||||||
|
margin-left: 5rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.origin-price-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
font-weight: 400;
|
||||||
|
text-decoration: line-through;
|
||||||
|
color: $gray-c;
|
||||||
|
font-family: OPPOSANS;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '¥';
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
|
@ -1,7 +1,11 @@
|
||||||
import { ref } from 'vue';
|
import {
|
||||||
|
ref
|
||||||
|
} from 'vue';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import $url from '@/sheep/url';
|
import $url from '@/sheep/url';
|
||||||
import { formatDate } from '@/sheep/util';
|
import {
|
||||||
|
formatDate
|
||||||
|
} from '@/sheep/util';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化销量
|
* 格式化销量
|
||||||
|
@ -80,7 +84,10 @@ export function formatGoodsSwiper(urlList) {
|
||||||
const isVideo = VIDEO_SUFFIX_LIST.some(suffix => url.includes(suffix));
|
const isVideo = VIDEO_SUFFIX_LIST.some(suffix => url.includes(suffix));
|
||||||
const type = isVideo ? 'video' : 'image'
|
const type = isVideo ? 'video' : 'image'
|
||||||
const src = $url.cdn(url);
|
const src = $url.cdn(url);
|
||||||
return { type, src }
|
return {
|
||||||
|
type,
|
||||||
|
src
|
||||||
|
}
|
||||||
}) || [];
|
}) || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,9 +101,9 @@ export function formatOrderColor(order) {
|
||||||
if (order.status === 0) {
|
if (order.status === 0) {
|
||||||
return 'info-color';
|
return 'info-color';
|
||||||
}
|
}
|
||||||
if (order.status === 10
|
if (order.status === 10 ||
|
||||||
|| order.status === 20
|
order.status === 20 ||
|
||||||
|| (order.status === 30 && !order.commentStatus)) {
|
(order.status === 30 && !order.commentStatus)) {
|
||||||
return 'warning-color';
|
return 'warning-color';
|
||||||
}
|
}
|
||||||
if (order.status === 30 && order.commentStatus) {
|
if (order.status === 30 && order.commentStatus) {
|
||||||
|
@ -387,3 +394,92 @@ export function formatRewardActivityRule(activity, rule) {
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
// 新增将时间搓转换为开始时间-结束时间的格式
|
||||||
|
export function formatDateRange(startTimestamp, endTimestamp) {
|
||||||
|
// 定义一个辅助函数来格式化时间戳为 YYYY.MM.DD 格式
|
||||||
|
const formatDate = (timestamp) => {
|
||||||
|
const date = new Date(timestamp);
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始,所以需要+1
|
||||||
|
const day = String(date.getDate()).padStart(2, '0');
|
||||||
|
return `${year}.${month}.${day}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 格式化开始和结束时间
|
||||||
|
const start = formatDate(startTimestamp);
|
||||||
|
const end = formatDate(endTimestamp);
|
||||||
|
|
||||||
|
// 返回格式化的日期范围
|
||||||
|
return `${start}-${end}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//处理活动信息
|
||||||
|
export function handList(orders) {
|
||||||
|
const typeMap = {
|
||||||
|
'1': '秒杀活动',
|
||||||
|
'2': '砍价活动',
|
||||||
|
'3': '拼团活动',
|
||||||
|
'4': '限时折扣',
|
||||||
|
'5': '满减送',
|
||||||
|
'6': '会员折扣',
|
||||||
|
'7': '优惠券',
|
||||||
|
'8': '积分'
|
||||||
|
};
|
||||||
|
|
||||||
|
// 给每个订单对象添加 typeName 属性
|
||||||
|
let updatedOrders = orders.map(order => {
|
||||||
|
return {
|
||||||
|
...order, // 展开现有的订单对象属性
|
||||||
|
typeName: typeMap[order.type] // 添加 typeName 属性
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return updatedOrders
|
||||||
|
};
|
||||||
|
//根据skuid来修改价格并添加时间
|
||||||
|
export function handListPrice(array,array2) {
|
||||||
|
// 将 array2 转换为一个以 skuId 为键的对象,以便于快速查找
|
||||||
|
const array2Map = array2.reduce((acc, item) => {
|
||||||
|
acc[item.skuId] = { price: item.price, type: item.type,endTime:item.endTime };
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
// 遍历 array 数组并更新 price 和 type
|
||||||
|
array.forEach(item => {
|
||||||
|
if (array2Map[item.id]) {
|
||||||
|
item.oldPrice = item.price
|
||||||
|
// 如果在 array2Map 中找到了对应的 skuId(即 id)
|
||||||
|
item.price = array2Map[item.id].price;
|
||||||
|
item.type = array2Map[item.id].type;
|
||||||
|
item.endTime = array2Map[item.id].endTime;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 返回更新后的 array
|
||||||
|
return array;
|
||||||
|
};
|
||||||
|
|
||||||
|
//处理活动数据
|
||||||
|
export function handActitList(rules) {
|
||||||
|
const rules2 = {
|
||||||
|
reduc: rules.map(item => ({
|
||||||
|
discountPrice: item.discountPrice,
|
||||||
|
limit: item.limit,
|
||||||
|
bull: true // 默认为 true
|
||||||
|
})),
|
||||||
|
cou: rules.map(item => ({
|
||||||
|
discountPrice: item.discountPrice,
|
||||||
|
value: item.couponCounts.reduce((acc, count) => acc + count, 0), // 计算 couponCounts 中各项之和
|
||||||
|
bull: item.givePoint // 对应 givePoint
|
||||||
|
})),
|
||||||
|
ship: rules.map(item => ({
|
||||||
|
discountPrice: item.discountPrice,
|
||||||
|
bull: item.freeDelivery // 对应 freeDelivery
|
||||||
|
})),
|
||||||
|
scor: rules.map(item => ({
|
||||||
|
discountPrice: item.discountPrice,
|
||||||
|
value: item.point, // 直接使用 point
|
||||||
|
bull: item.givePoint // 对应 givePoint
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
return rules2
|
||||||
|
};
|
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Loading…
Reference in New Issue