修复详情页

pull/100/head
岳琳红 2024-09-12 16:42:52 +08:00
parent e4da107e69
commit d1eea3280c
8 changed files with 1702 additions and 1716 deletions

View File

@ -1,385 +1,433 @@
<!-- 秒杀活动列表 --> <!-- 秒杀活动列表 -->
<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 class="header" v-if="activeTimeConfig?.sliderPicUrls?.length > 0">
></view> <swiper indicator-dots="true" autoplay="true" :circular="true" interval="3000" duration="1500"
<!-- 时间段轮播图 --> indicator-color="rgba(255,255,255,0.6)" indicator-active-color="#fff">
<view class="header" v-if="activeTimeConfig?.sliderPicUrls?.length > 0"> <block v-for="(picUrl, index) in activeTimeConfig.sliderPicUrls" :key="index">
<swiper indicator-dots="true" autoplay="true" :circular="true" interval="3000" duration="1500" <swiper-item class="borRadius14">
indicator-color="rgba(255,255,255,0.6)" indicator-active-color="#fff"> <image :src="picUrl" class="slide-image borRadius14" lazy-load />
<block v-for="(picUrl, index) in activeTimeConfig.sliderPicUrls" :key="index"> </swiper-item>
<swiper-item class="borRadius14"> </block>
<image :src="picUrl" class="slide-image borRadius14" lazy-load /> </swiper>
</swiper-item> </view>
</block> <!-- 时间段列表 -->
</swiper> <view class="flex align-center justify-between ss-p-25">
</view> <!-- 左侧图标 -->
<!-- 时间段列表 --> <view class="time-icon">
<view class="flex align-center justify-between ss-p-25"> <!-- TODO 芋艿图片统一维护 -->
<!-- 左侧图标 --> <image class="ss-w-100 ss-h-100" src="http://mall.yudao.iocoder.cn/static/images/priceTag.png" />
<view class="time-icon"> </view>
<!-- TODO 芋艿图片统一维护 --> <scroll-view class="time-list" :scroll-into-view="activeTimeElId" scroll-x scroll-with-animation>
<image class="ss-w-100 ss-h-100" src="http://mall.yudao.iocoder.cn/static/images/priceTag.png" /> <view v-for="(config, index) in timeConfigList" :key="index"
</view> :class="['item', { active: activeTimeIndex === index}]" :id="`timeItem${index}`"
<scroll-view class="time-list" :scroll-into-view="activeTimeElId" scroll-x scroll-with-animation> @tap="handleChangeTimeConfig(index,config.id)">
<view v-for="(config, index) in timeConfigList" :key="index" <!-- 活动起始时间 -->
:class="['item', { active: activeTimeIndex === index}]" <view class="time">{{ config.startTime }}</view>
:id="`timeItem${index}`" <!-- 活动状态 -->
@tap="handleChangeTimeConfig(index)"> <view class="status">{{ config?.status }}</view>
<!-- 活动起始时间 --> </view>
<view class="time">{{ config.startTime }}</view> </scroll-view>
<!-- 活动状态 --> </view>
<view class="status">{{ config.status }}</view>
</view>
</scroll-view>
</view>
<!-- 内容区 --> <!-- 内容区 -->
<view class="list-content"> <view class="list-content">
<!-- 活动倒计时 --> <!-- 活动倒计时 -->
<view class="content-header ss-flex-col ss-col-center ss-row-center"> <view class="content-header ss-flex-col ss-col-center ss-row-center">
<view class="content-header-box ss-flex ss-row-center"> <view class="content-header-box ss-flex ss-row-center">
<view class="countdown-box ss-flex" v-if="activeTimeConfig?.status === TimeStatusEnum.STARTED"> <view class="countdown-box ss-flex" v-if="activeTimeConfig?.status === TimeStatusEnum.STARTED">
<view class="countdown-title ss-m-r-12">距结束</view> <view class="countdown-title ss-m-r-12">距结束</view>
<view class="ss-flex countdown-time"> <view class="ss-flex countdown-time">
<view class="ss-flex countdown-h">{{ countDown.h }}</view> <view class="ss-flex countdown-h">{{ countDown.h }}</view>
<view class="ss-m-x-4">:</view> <view class="ss-m-x-4">:</view>
<view class="countdown-num ss-flex ss-row-center">{{ countDown.m }}</view> <view class="countdown-num ss-flex ss-row-center">{{ countDown.m }}</view>
<view class="ss-m-x-4">:</view> <view class="ss-m-x-4">:</view>
<view class="countdown-num ss-flex ss-row-center">{{ countDown.s }}</view> <view class="countdown-num ss-flex ss-row-center">{{ countDown.s }}</view>
</view> </view>
</view> </view>
<view v-else> {{ activeTimeConfig?.status }} </view> <view v-else> {{ activeTimeConfig?.status }} </view>
</view> </view>
</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' }" <view class="goods-box ss-m-b-20" v-for="activity in activityList" :key="activity.id">
scroll-y="true" <s-goods-column size="lg" :data="{ ...activity, price: activity.seckillPrice }"
:scroll-with-animation="false" :goodsFields="goodsFields" :seckillTag="true">
:enable-back-to-top="true" <!-- 抢购进度 -->
> <template #activity>
<view class="goods-box ss-m-b-20" v-for="activity in activityList" :key="activity.id"> <view class="limit">限量 <text class="ss-m-l-5">{{ activity.stock}}
<s-goods-column {{activity.unitName}}</text></view>
size="lg" <su-progress :percentage="activity.percent" strokeWidth="10" textInside isAnimate />
:data="{ ...activity, price: activity.seckillPrice }" </template>
:goodsFields="goodsFields" <!-- 抢购按钮 -->
:seckillTag="true" <template #cart>
@click="sheep.$router.go('/pages/goods/seckill', { id: activity.id })" <button
> :class="['ss-reset-button cart-btn', { disabled: activeTimeConfig?.status === TimeStatusEnum.END}]"
<!-- 抢购进度 --> v-if="activeTimeConfig?.status === TimeStatusEnum.WAIT_START">
<template #activity> <span>未开始</span>
<view class="limit">限量 <text class="ss-m-l-5">{{ activity.stock}} {{activity.unitName}}</text></view> </button>
<su-progress :percentage="activity.percent" strokeWidth="10" textInside isAnimate /> <button
</template> :class="['ss-reset-button cart-btn', { disabled: activeTimeConfig?.status === TimeStatusEnum.END}]"
<!-- 抢购按钮 --> @click="sheep.$router.go('/pages/goods/seckill', { id: activity.id })"
<template #cart> v-else-if='activeTimeConfig?.status === TimeStatusEnum.STARTED'>
<button :class="['ss-reset-button cart-btn', { disabled: activeTimeConfig.status === TimeStatusEnum.END }]"> <span>马上抢</span>
<span v-if="activeTimeConfig?.status === TimeStatusEnum.WAIT_START"></span> </button>
<span v-else-if="activeTimeConfig?.status === TimeStatusEnum.STARTED">马上抢</span> <button
<span v-else></span> :class="['ss-reset-button cart-btn', { disabled: activeTimeConfig?.status === TimeStatusEnum.END}]"
</button> v-else>
</template> <span>已结束</span>
</s-goods-column> </button>
</view> </template>
<uni-load-more </s-goods-column>
v-if="activityTotal > 0" </view>
:status="loadStatus" <uni-load-more v-if="activityTotal > 0" :status="loadStatus" :content-text="{
:content-text="{
contentdown: '上拉加载更多', contentdown: '上拉加载更多',
}" }" @tap="loadMore" />
@tap="loadMore" </scroll-view>
/> </view>
</scroll-view> </s-layout>
</view>
</s-layout>
</template> </template>
<script setup> <script setup>
import {reactive, computed, ref, nextTick} from 'vue'; import {
import { onLoad, onReachBottom } from '@dcloudio/uni-app'; reactive,
import sheep from '@/sheep'; computed,
import { useDurationTime } from '@/sheep/hooks/useGoods'; ref,
import SeckillApi from "@/sheep/api/promotion/seckill"; nextTick
import dayjs from "dayjs"; } from 'vue';
import {TimeStatusEnum} from "@/sheep/util/const"; import {
onLoad,
onReachBottom
} from '@dcloudio/uni-app';
import sheep from '@/sheep';
import {
useDurationTime
} from '@/sheep/hooks/useGoods';
import SeckillApi from "@/sheep/api/promotion/seckill";
import dayjs from "dayjs";
import {
TimeStatusEnum
} from "@/sheep/util/const";
// //
const { safeAreaInsets, safeArea } = sheep.$platform.device; const {
const statusBarHeight = sheep.$platform.device.statusBarHeight * 2; safeAreaInsets,
const pageHeight = (safeArea.height + safeAreaInsets.bottom) * 2 + statusBarHeight - sheep.$platform.navbar - 350; safeArea
const headerBg = sheep.$url.css('/static/img/shop/goods/seckill-header.png'); } = sheep.$platform.device;
const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
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 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
// //
const timeConfigList = ref([]) const timeConfigList = ref([])
// //
const getSeckillConfigList = async () => { const getSeckillConfigList = async () => {
const { data } = await SeckillApi.getSeckillConfigList() const {
const now = dayjs(); data
const today = now.format('YYYY-MM-DD') } = await SeckillApi.getSeckillConfigList()
// const now = dayjs();
data.forEach((config, index) => { const today = now.format('YYYY-MM-DD')
const startTime = dayjs(`${today} ${config.startTime}`) const select = ref([])
const endTime = dayjs(`${today} ${config.endTime}`) console.log('数据', data)
if (now.isBefore(startTime)) { //
config.status = TimeStatusEnum.WAIT_START; data.forEach((config, index) => {
} else if (now.isAfter(endTime)) { const startTime = dayjs(`${today} ${config.startTime}`)
config.status = TimeStatusEnum.END; const endTime = dayjs(`${today} ${config.endTime}`)
} else { select.value[index] = config.id;
config.status = TimeStatusEnum.STARTED; if (now.isBefore(startTime)) {
activeTimeIndex.value = index; config.status = TimeStatusEnum.WAIT_START;
} // select.value[index] = config.id;
}) console.log('未开始',select.value,activeTimeIndex.value)
timeConfigList.value = data } else if (now.isAfter(endTime)) {
// config.status = TimeStatusEnum.END;
handleChangeTimeConfig(activeTimeIndex.value); // select.value[index] = config.id;
// console.log('已结束',select.value,activeTimeIndex.value)
scrollToTimeConfig(activeTimeIndex.value) } else {
} config.status = TimeStatusEnum.STARTED;
// select.value[index] = config.id;
activeTimeIndex.value = index
console.log('进行中',select.value,activeTimeIndex.value)
}
})
timeConfigList.value = data
console.log('传递',select.value,activeTimeIndex.value)
//
handleChangeTimeConfig(activeTimeIndex.value, select.value[activeTimeIndex.value]);
//
scrollToTimeConfig(activeTimeIndex.value)
}
// //
const activeTimeElId = ref('') // ID const activeTimeElId = ref('') // ID
const scrollToTimeConfig = (index) => { const scrollToTimeConfig = (index) => {
nextTick(() => activeTimeElId.value = `timeItem${index}`) nextTick(() => activeTimeElId.value = `timeItem${index}`)
} }
// //
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 console.log('点击',index + '+' + id)
activeTimeIndex.value = index
// //
activityPageParams.pageNo = 1 activityPageParams.pageNo = 1
activityList.value = [] activityPageParams.configId = id;
getActivityList(); activityList.value = []
} getActivityList();
}
// //
const countDown = computed(() => { const countDown = computed(() => {
const endTime = activeTimeConfig.value?.endTime const endTime = activeTimeConfig.value?.endTime
if (endTime) { if (endTime) {
return useDurationTime(`${dayjs().format('YYYY-MM-DD')} ${endTime}`); return useDurationTime(`${dayjs().format('YYYY-MM-DD')} ${endTime}`);
} }
}); });
//#endregion //#endregion
//#region //#region
// //
const activityPageParams = reactive({ const activityPageParams = reactive({
id: 0, // ID configId: 0, // ID
pageNo: 1, // pageNo: 1, //
pageSize: 5, // pageSize: 5, //
}) })
const activityTotal = ref(0) // const activityTotal = ref(0) //
const activityList = ref([]) // const activityList = ref([]) //
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.list.forEach(activity => { data
// } = await SeckillApi.getSeckillActivityPage(activityPageParams)
activity.percent = parseInt(100 * (activity.totalStock - activity.stock) / activity.totalStock); data.list.forEach(activity => {
}) //
activityList.value = activityList.value.concat(...data.list); activity.percent = parseInt(100 * (activity.totalStock - activity.stock) / activity.totalStock);
activityTotal.value = data.total; })
activityList.value = activityList.value.concat(...data.list);
activityTotal.value = data.total;
loadStatus.value = activityList.value.length < activityTotal.value ? 'more' : 'noMore'; loadStatus.value = activityList.value.length < activityTotal.value ? 'more' : 'noMore';
} }
// //
function loadMore() { function loadMore() {
if (loadStatus.value !== 'noMore') { if (loadStatus.value !== 'noMore') {
activityPageParams.pageNo += 1 activityPageParams.pageNo += 1
getActivityList(); getActivityList();
} }
} }
// //
onReachBottom(() => loadMore()); onReachBottom(() => loadMore());
//#endregion //#endregion
// //
onLoad(async () => { onLoad(async () => {
await getSeckillConfigList() await getSeckillConfigList()
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
// //
.page-bg { .page-bg {
width: 100%; width: 100%;
height: 458rpx; height: 458rpx;
background: v-bind(headerBg) no-repeat; background: v-bind(headerBg) no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
} }
// //
.header { .header {
width: 710rpx; width: 710rpx;
height: 330rpx; height: 330rpx;
margin: -276rpx auto 0 auto; margin: -276rpx auto 0 auto;
border-radius: 14rpx; border-radius: 14rpx;
overflow: hidden; overflow: hidden;
swiper{
height: 330rpx !important;
border-radius: 14rpx;
overflow: hidden;
}
image { swiper {
width: 100%; height: 330rpx !important;
height: 100%; border-radius: 14rpx;
border-radius: 14rpx; overflow: hidden;
overflow: hidden; }
img{
border-radius: 14rpx;
}
}
}
// image {
.time-icon { width: 100%;
width: 75rpx; height: 100%;
height: 70rpx; border-radius: 14rpx;
} overflow: hidden;
//
.time-list {
width: 596rpx;
white-space: nowrap;
//
.item {
display: inline-block;
font-size: 20rpx;
color: #666;
text-align: center;
box-sizing: border-box;
margin-right: 30rpx;
width: 130rpx;
//
.time {
font-size: 36rpx;
font-weight: 600;
color: #333;
}
//
&.active {
.time {
color: var(--ui-BG-Main);
}
//
.status {
height: 30rpx;
line-height: 30rpx;
border-radius: 15rpx;
width: 128rpx;
background: linear-gradient(90deg, var(--ui-BG-Main) 0%, var(--ui-BG-Main-gradient) 100%);
color: #fff;
}
}
}
}
// img {
.list-content { border-radius: 14rpx;
position: relative; }
z-index: 3; }
margin: 0 20rpx 0 20rpx; }
background: #fff;
border-radius: 20rpx 20rpx 0 0;
.content-header {
width: 100%;
border-radius: 20rpx 20rpx 0 0;
height: 150rpx;
background: linear-gradient(180deg, #fff4f7, #ffe6ec);
.content-header-box { //
width: 678rpx; .time-icon {
height: 64rpx; width: 75rpx;
background: rgba($color: #fff, $alpha: 0.66); height: 70rpx;
border-radius: 32px; }
//
.countdown-title {
font-size: 28rpx;
font-weight: 500;
color: #333333;
line-height: 28rpx;
}
//
.countdown-time {
font-size: 28rpx;
color: rgba(#ed3c30, 0.23);
//
.countdown-h {
font-size: 24rpx;
font-family: OPPOSANS;
font-weight: 500;
color: #ffffff;
padding: 0 4rpx;
height: 40rpx;
background: rgba(#ed3c30, 0.23);
border-radius: 6rpx;
}
//
.countdown-num {
font-size: 24rpx;
font-family: OPPOSANS;
font-weight: 500;
color: #ffffff;
width: 40rpx;
height: 40rpx;
background: rgba(#ed3c30, 0.23);
border-radius: 6rpx;
}
}
}
}
//
.scroll-box {
height: 900rpx;
//
.goods-box {
position: relative;
//
.cart-btn {
position: absolute;
bottom: 10rpx;
right: 20rpx;
z-index: 11;
height: 44rpx;
line-height: 50rpx;
padding: 0 20rpx;
border-radius: 25rpx;
font-size: 24rpx;
color: #fff;
background: linear-gradient(90deg, #ff6600 0%, #fe832a 100%);
&.disabled { //
background: $gray-b; .time-list {
color: #fff; width: 596rpx;
} white-space: nowrap;
}
// //
.limit { .item {
font-size: 22rpx; display: inline-block;
color: $dark-9; font-size: 20rpx;
margin-bottom: 5rpx; color: #666;
} text-align: center;
} box-sizing: border-box;
} margin-right: 30rpx;
} width: 130rpx;
//
.time {
font-size: 36rpx;
font-weight: 600;
color: #333;
}
//
&.active {
.time {
color: var(--ui-BG-Main);
}
//
.status {
height: 30rpx;
line-height: 30rpx;
border-radius: 15rpx;
width: 128rpx;
background: linear-gradient(90deg, var(--ui-BG-Main) 0%, var(--ui-BG-Main-gradient) 100%);
color: #fff;
}
}
}
}
//
.list-content {
position: relative;
z-index: 3;
margin: 0 20rpx 0 20rpx;
background: #fff;
border-radius: 20rpx 20rpx 0 0;
.content-header {
width: 100%;
border-radius: 20rpx 20rpx 0 0;
height: 150rpx;
background: linear-gradient(180deg, #fff4f7, #ffe6ec);
.content-header-box {
width: 678rpx;
height: 64rpx;
background: rgba($color: #fff, $alpha: 0.66);
border-radius: 32px;
//
.countdown-title {
font-size: 28rpx;
font-weight: 500;
color: #333333;
line-height: 28rpx;
}
//
.countdown-time {
font-size: 28rpx;
color: rgba(#ed3c30, 0.23);
//
.countdown-h {
font-size: 24rpx;
font-family: OPPOSANS;
font-weight: 500;
color: #ffffff;
padding: 0 4rpx;
height: 40rpx;
background: rgba(#ed3c30, 0.23);
border-radius: 6rpx;
}
//
.countdown-num {
font-size: 24rpx;
font-family: OPPOSANS;
font-weight: 500;
color: #ffffff;
width: 40rpx;
height: 40rpx;
background: rgba(#ed3c30, 0.23);
border-radius: 6rpx;
}
}
}
}
//
.scroll-box {
height: 900rpx;
//
.goods-box {
position: relative;
//
.cart-btn {
position: absolute;
bottom: 10rpx;
right: 20rpx;
z-index: 11;
height: 44rpx;
line-height: 50rpx;
padding: 0 20rpx;
border-radius: 25rpx;
font-size: 24rpx;
color: #fff;
background: linear-gradient(90deg, #ff6600 0%, #fe832a 100%);
&.disabled {
background: $gray-b;
color: #fff;
}
}
//
.limit {
font-size: 22rpx;
color: $dark-9;
margin-bottom: 5rpx;
}
}
}
}
</style> </style>

View File

@ -207,7 +207,7 @@
// //
function onBuy(e) { function onBuy(e) {
if (!state.selectedSku.id) { if (!e.id) {
sheep.$helper.toast('请选择商品规格'); sheep.$helper.toast('请选择商品规格');
return; return;
} }
@ -536,7 +536,7 @@
} }
.disContT1 { .disContT1 {
width: 300rpx; width: 400rpx;
height: 50rpx; height: 50rpx;
// background-color: green; // background-color: green;
display: flex; display: flex;
@ -545,10 +545,10 @@
} }
.disContT2 { .disContT2 {
width: 300rpx; width: 200rpx;
height: 50rpx; height: 50rpx;
line-height: 50rpx; line-height: 50rpx;
// background-color: green; // background-color: gold;
font-size: 30rpx; font-size: 30rpx;
text-align: end; text-align: end;
color: white; color: white;

File diff suppressed because it is too large Load Diff

View File

@ -1,462 +1,433 @@
<template> <template>
<s-layout title="确认订单"> <s-layout title="确认订单">
<!-- 头部地址选择配送地址自提地址 --> <!-- 头部地址选择配送地址自提地址 -->
<AddressSelection v-model="addressState" @change="getOrderInfo()"/> <AddressSelection v-model="addressState" @change="getOrderInfo()" />
<!-- 商品信息 --> <!-- 商品信息 -->
<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" <view class="order-item ss-flex ss-col-center ss-row-between ss-p-x-20 bg-white ss-r-10">
:title="item.spuName" <view class="item-title">订单备注</view>
:skuText="item.properties.map((property) => property.valueName).join(' ')" <view class="ss-flex ss-col-center">
:price="item.price" <uni-easyinput maxlength="20" placeholder="建议留言前先与商家沟通" v-model="state.orderPayload.remark"
:num="item.count" :inputBorder="false" :clearable="false" />
marginBottom="10" </view>
/> </view>
<view class="order-item ss-flex ss-col-center ss-row-between ss-p-x-20 bg-white ss-r-10"> </view>
<view class="item-title">订单备注</view>
<view class="ss-flex ss-col-center">
<uni-easyinput
maxlength="20"
placeholder="建议留言前先与商家沟通"
v-model="state.orderPayload.remark"
:inputBorder="false"
:clearable="false"
/>
</view>
</view>
</view>
<!-- 价格信息 --> <!-- 价格信息 -->
<view class="bg-white total-card-box ss-p-20 ss-m-b-14 ss-r-10"> <view class="bg-white total-card-box ss-p-20 ss-m-b-14 ss-r-10">
<view class="total-box-content border-bottom"> <view class="total-box-content border-bottom">
<view class="order-item ss-flex ss-col-center ss-row-between"> <view class="order-item ss-flex ss-col-center ss-row-between">
<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">
{{ fen2yuan(state.orderInfo.price.totalPrice) }} {{ fen2yuan(state.orderInfo.price.totalPrice) }}
</text> </text>
</view> </view>
</view> </view>
<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" <view class="item-title">积分抵扣</view>
v-if="state.orderInfo.type === 0" <view class="ss-flex ss-col-center">
> {{ state.pointStatus ? '剩余积分' : '当前积分' }}
<view class="item-title">积分抵扣</view> <image :src="sheep.$url.static('/static/img/shop/goods/score1.svg')" class="score-img" />
<view class="ss-flex ss-col-center"> <text class="item-value ss-m-r-24">
{{ state.pointStatus ? '剩余积分' : '当前积分' }} {{ state.pointStatus ? state.orderInfo.totalPoint - state.orderInfo.usePoint : (state.orderInfo.totalPoint || 0) }}
<image </text>
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')" <checkbox-group @change="changeIntegral">
class="score-img" <checkbox :checked='state.pointStatus'
/> :disabled="!state.orderInfo.totalPoint || state.orderInfo.totalPoint <= 0" />
<text class="item-value ss-m-r-24"> </checkbox-group>
{{ state.pointStatus ? state.orderInfo.totalPoint - state.orderInfo.usePoint : (state.orderInfo.totalPoint || 0) }} </view>
</text> </view>
<checkbox-group @change="changeIntegral"> <!-- 快递配置时信息的展示 -->
<checkbox :checked='state.pointStatus' :disabled="!state.orderInfo.totalPoint || state.orderInfo.totalPoint <= 0" /> <view class="order-item ss-flex ss-col-center ss-row-between" v-if='addressState.deliveryType === 1'>
</checkbox-group> <view class="item-title">运费</view>
</view> <view class="ss-flex ss-col-center">
</view> <text class="item-value ss-m-r-24" v-if="state.orderInfo.price.deliveryPrice > 0">
<!-- 快递配置时信息的展示 --> +{{ fen2yuan(state.orderInfo.price.deliveryPrice) }}
<view class="order-item ss-flex ss-col-center ss-row-between" v-if='addressState.deliveryType === 1'> </text>
<view class="item-title">运费</view> <view class='item-value ss-m-r-24' v-else></view>
<view class="ss-flex ss-col-center"> </view>
<text class="item-value ss-m-r-24" v-if="state.orderInfo.price.deliveryPrice > 0"> </view>
+{{ fen2yuan(state.orderInfo.price.deliveryPrice) }} <!-- 门店自提时需要填写姓名和手机号 -->
</text> <view class="order-item ss-flex ss-col-center ss-row-between" v-if='addressState.deliveryType === 2'>
<view class='item-value ss-m-r-24' v-else></view> <view class="item-title">联系人</view>
</view> <view class="ss-flex ss-col-center">
</view> <uni-easyinput maxlength="20" placeholder="请填写您的联系姓名" v-model="addressState.receiverName"
<!-- 门店自提时需要填写姓名和手机号 --> :inputBorder="false" :clearable="false" />
<view class="order-item ss-flex ss-col-center ss-row-between" v-if='addressState.deliveryType === 2'> </view>
<view class="item-title">联系人</view> </view>
<view class="ss-flex ss-col-center"> <view class="order-item ss-flex ss-col-center ss-row-between" v-if='addressState.deliveryType === 2'>
<uni-easyinput <view class="item-title">联系电话</view>
maxlength="20" <view class="ss-flex ss-col-center">
placeholder="请填写您的联系姓名" <uni-easyinput maxlength="20" placeholder="请填写您的联系电话" v-model="addressState.receiverMobile"
v-model="addressState.receiverName" :inputBorder="false" :clearable="false" />
:inputBorder="false" </view>
:clearable="false" </view>
/> <!-- 优惠劵只有 type = 0 普通订单非拼团秒杀砍价才可以使用优惠劵 -->
</view> <view class="order-item ss-flex ss-col-center ss-row-between" v-if="state.orderInfo.type === 0">
</view> <view class="item-title">优惠券</view>
<view class="order-item ss-flex ss-col-center ss-row-between" v-if='addressState.deliveryType === 2'> <view class="ss-flex ss-col-center" @tap="state.showCoupon = true">
<view class="item-title">联系电话</view> <text class="item-value text-red" v-if="state.orderPayload.couponId > 0">
<view class="ss-flex ss-col-center"> -{{ fen2yuan(state.orderInfo.price.couponPrice) }}
<uni-easyinput </text>
maxlength="20" <text class="item-value" :class="couponNumber > 0 ? 'text-red' : 'text-disabled'" v-else>
placeholder="请填写您的联系电话" {{
v-model="addressState.receiverMobile"
:inputBorder="false"
:clearable="false"
/>
</view>
</view>
<!-- 优惠劵只有 type = 0 普通订单非拼团秒杀砍价才可以使用优惠劵 -->
<view
class="order-item ss-flex ss-col-center ss-row-between"
v-if="state.orderInfo.type === 0"
>
<view class="item-title">优惠券</view>
<view class="ss-flex ss-col-center" @tap="state.showCoupon = true">
<text class="item-value text-red" v-if="state.orderPayload.couponId > 0">
-{{ fen2yuan(state.orderInfo.price.couponPrice) }}
</text>
<text
class="item-value"
:class="couponNumber > 0 ? 'text-red' : 'text-disabled'"
v-else
>
{{
couponNumber > 0 ? couponNumber + ' 张可用' : '暂无可用优惠券' 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="ss-flex ss-col-center" @tap="state.showDiscount = true">
<view class="item-title">活动优惠</view> <text class="item-value text-red">
<view class="ss-flex ss-col-center" @tap="state.showDiscount = true"> -{{ fen2yuan(state.orderInfo.price.discountPrice) }}
<text class="item-value text-red"> </text>
-{{ fen2yuan(state.orderInfo.price.discountPrice) }} <text class="_icon-forward item-icon" />
</text> </view>
<text class="_icon-forward item-icon" /> </view>
</view> <view class="order-item ss-flex ss-col-center ss-row-between" v-if="state.orderInfo.price.vipPrice > 0">
</view> <view class="item-title">会员优惠</view>
<view <view class="ss-flex ss-col-center">
class="order-item ss-flex ss-col-center ss-row-between" <text class="item-value text-red">
v-if="state.orderInfo.price.vipPrice > 0" -{{ fen2yuan(state.orderInfo.price.vipPrice) }}
> </text>
<view class="item-title">会员优惠</view> </view>
<view class="ss-flex ss-col-center"> </view>
<text class="item-value text-red"> </view>
-{{ fen2yuan(state.orderInfo.price.vipPrice) }} <view class="total-box-footer ss-font-28 ss-flex ss-row-right ss-col-center ss-m-r-28">
</text> <view class="total-num ss-m-r-20">
</view> {{ state.orderInfo.items.reduce((acc, item) => acc + item.count, 0) }}
</view> </view>
</view> <view>合计</view>
<view class="total-box-footer ss-font-28 ss-flex ss-row-right ss-col-center ss-m-r-28"> <view class="total-num text-red"> {{ fen2yuan(state.orderInfo.price.payPrice) }}</view>
<view class="total-num ss-m-r-20"> </view>
{{ state.orderInfo.items.reduce((acc, item) => acc + item.count, 0) }} </view>
</view>
<view>合计</view>
<view class="total-num text-red"> {{ fen2yuan(state.orderInfo.price.payPrice) }}</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">
<view class="footer-box border-top ss-flex ss-row-between ss-p-x-20 ss-col-center"> <view class="footer-box border-top ss-flex ss-row-between ss-p-x-20 ss-col-center">
<view class="total-box-footer ss-flex ss-col-center"> <view class="total-box-footer ss-flex ss-col-center">
<view class="total-num ss-font-30 text-red"> <view class="total-num ss-font-30 text-red">
{{ 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>
> </view>
提交订单 </su-fixed>
</button> </s-layout>
</view>
</su-fixed>
</s-layout>
</template> </template>
<script setup> <script setup>
import { reactive, ref } from 'vue'; import {
import { onLoad } from '@dcloudio/uni-app'; reactive,
import AddressSelection from '@/pages/order/addressSelection.vue'; ref
import sheep from '@/sheep'; } from 'vue';
import OrderApi from '@/sheep/api/trade/order'; import {
import CouponApi from '@/sheep/api/promotion/coupon'; onLoad
import { fen2yuan } from '@/sheep/hooks/useGoods'; } from '@dcloudio/uni-app';
import AddressSelection from '@/pages/order/addressSelection.vue';
import sheep from '@/sheep';
import OrderApi from '@/sheep/api/trade/order';
import CouponApi from '@/sheep/api/promotion/coupon';
import {
fen2yuan
} from '@/sheep/hooks/useGoods';
const state = reactive({ const state = reactive({
orderPayload: {}, orderPayload: {},
orderInfo: { orderInfo: {
items: [], // items: [], //
price: {}, // price: {}, //
}, },
showCoupon: false, // showCoupon: false, //
couponInfo: [], // couponInfo: [], //
showDiscount: false, // showDiscount: false, //
// ========== ========== // ========== ==========
pointStatus: false, //使 pointStatus: false, //使
}); });
const addressState = ref({ const addressState = ref({
addressInfo: {}, // addressInfo: {}, //
deliveryType: 1, // 1 - 2 - deliveryType: 1, // 1 - 2 -
isPickUp: true, // TODO puhui999: isPickUp: true, // TODO puhui999:
pickUpInfo: {}, // pickUpInfo: {}, //
receiverName: '', // receiverName: '', //
receiverMobile: '', // receiverMobile: '', //
}); });
// ========== ========== // ========== ==========
/** /**
* 使用积分抵扣 * 使用积分抵扣
*/ */
const changeIntegral = async () => { const changeIntegral = async () => {
state.pointStatus = !state.pointStatus; state.pointStatus = !state.pointStatus;
await getOrderInfo(); await getOrderInfo();
}; };
// //
async function onSelectCoupon(couponId) { async function onSelectCoupon(couponId) {
state.orderPayload.couponId = couponId || 0; state.orderPayload.couponId = couponId || 0;
await getOrderInfo(); await getOrderInfo();
state.showCoupon = false; state.showCoupon = false;
} }
// //
function onConfirm() { function onConfirm() {
if (addressState.value.deliveryType === 1 && !addressState.value.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.deliveryType === 2) {
if (!addressState.value.pickUpInfo.id) { if (!addressState.value.pickUpInfo.id) {
sheep.$helper.toast('请选择自提门店地址'); sheep.$helper.toast('请选择自提门店地址');
return; return;
} }
if (addressState.value.receiverName === '' || addressState.value.receiverMobile === '') { if (addressState.value.receiverName === '' || addressState.value.receiverMobile === '') {
sheep.$helper.toast('请填写联系人或联系人电话'); sheep.$helper.toast('请填写联系人或联系人电话');
return; return;
} }
if (!/^[\u4e00-\u9fa5\w]{2,16}$/.test(addressState.value.receiverName)) { if (!/^[\u4e00-\u9fa5\w]{2,16}$/.test(addressState.value.receiverName)) {
sheep.$helper.toast('请填写您的真实姓名'); sheep.$helper.toast('请填写您的真实姓名');
return; return;
} }
if (!/^1(3|4|5|7|8|9|6)\d{9}$/.test(addressState.value.receiverMobile)) { if (!/^1(3|4|5|7|8|9|6)\d{9}$/.test(addressState.value.receiverMobile)) {
sheep.$helper.toast('请填写正确的手机号'); sheep.$helper.toast('请填写正确的手机号');
return; return;
} }
} }
submitOrder(); submitOrder();
} }
// & // &
async function submitOrder() { async function submitOrder() {
const { code, data } = await OrderApi.createOrder({ const {
items: state.orderPayload.items, code,
couponId: state.orderPayload.couponId, data
remark: state.orderPayload.remark, } = await OrderApi.createOrder({
deliveryType: addressState.value.deliveryType, items: state.orderPayload.items,
addressId: addressState.value.addressInfo.id, // couponId: state.orderPayload.couponId,
pickUpStoreId: addressState.value.pickUpInfo.id,// remark: state.orderPayload.remark,
receiverName: addressState.value.receiverName,// deliveryType: addressState.value.deliveryType,
receiverMobile: addressState.value.receiverMobile,// addressId: addressState.value.addressInfo.id, //
pointStatus: state.pointStatus, pickUpStoreId: addressState.value.pickUpInfo.id, //
combinationActivityId: state.orderPayload.combinationActivityId, receiverName: addressState.value.receiverName, //
combinationHeadId: state.orderPayload.combinationHeadId, receiverMobile: addressState.value.receiverMobile, //
seckillActivityId: state.orderPayload.seckillActivityId, pointStatus: state.pointStatus,
}); combinationActivityId: state.orderPayload.combinationActivityId,
if (code !== 0) { combinationHeadId: state.orderPayload.combinationHeadId,
return; seckillActivityId: state.orderPayload.seckillActivityId,
} });
// if (code !== 0) {
if (state.orderPayload.items[0].cartId > 0) { return;
sheep.$store('cart').getList(); }
} //
if (state.orderPayload.items[0].cartId > 0) {
sheep.$store('cart').getList();
}
// //
sheep.$router.redirect('/pages/pay/index', { sheep.$router.redirect('/pages/pay/index', {
id: data.payOrderId, id: data.payOrderId,
}); });
} }
// & // &
async function getOrderInfo() { async function getOrderInfo() {
// //
const { data, code } = await OrderApi.settlementOrder({ const {
items: state.orderPayload.items, data,
couponId: state.orderPayload.couponId, code
deliveryType: addressState.value.deliveryType, } = await OrderApi.settlementOrder({
addressId: addressState.value.addressInfo.id, // items: state.orderPayload.items,
pickUpStoreId: addressState.value.pickUpInfo.id,// couponId: state.orderPayload.couponId,
receiverName: addressState.value.receiverName,// deliveryType: addressState.value.deliveryType,
receiverMobile: addressState.value.receiverMobile,// addressId: addressState.value.addressInfo.id, //
pointStatus: state.pointStatus, pickUpStoreId: addressState.value.pickUpInfo.id, //
combinationActivityId: state.orderPayload.combinationActivityId, receiverName: addressState.value.receiverName, //
combinationHeadId: state.orderPayload.combinationHeadId, receiverMobile: addressState.value.receiverMobile, //
seckillActivityId: state.orderPayload.seckillActivityId, pointStatus: state.pointStatus,
}); combinationActivityId: state.orderPayload.combinationActivityId,
if (code !== 0) { combinationHeadId: state.orderPayload.combinationHeadId,
return; seckillActivityId: state.orderPayload.seckillActivityId,
} });
state.orderInfo = data; if (code !== 0) {
// setTimeout(() => {
if (state.orderInfo.address) { uni.navigateBack({
addressState.value.addressInfo = state.orderInfo.address; delta: 1
} })
} }, 1500)
return;
}
state.orderInfo = data;
//
if (state.orderInfo.address) {
addressState.value.addressInfo = state.orderInfo.address;
}
}
// //
let couponNumber = ref(0) let couponNumber = ref(0)
async function getCoupons() { async function getCoupons() {
const { code, data } = await CouponApi.getMatchCouponList( const {
state.orderInfo.price.payPrice, code,
state.orderInfo.items.map((item) => item.spuId), data
state.orderPayload.items.map((item) => item.skuId), } = await CouponApi.getMatchCouponList(
state.orderPayload.items.map((item) => item.categoryId), state.orderInfo.price.payPrice,
); state.orderInfo.items.map((item) => item.spuId),
if (code === 0) { state.orderPayload.items.map((item) => item.skuId),
state.couponInfo = data; state.orderPayload.items.map((item) => item.categoryId),
couponNumber.value = state.couponInfo.filter(item => item.match).length; );
} if (code === 0) {
} state.couponInfo = data;
couponNumber.value = state.couponInfo.filter(item => item.match).length;
}
}
onLoad(async (options) => { onLoad(async (options) => {
if (!options.data) { if (!options.data) {
sheep.$helper.toast('参数不正确,请检查!'); sheep.$helper.toast('参数不正确,请检查!');
return; return;
} }
state.orderPayload = JSON.parse(options.data); state.orderPayload = JSON.parse(options.data);
await getOrderInfo(); await getOrderInfo();
await getCoupons(); await getCoupons();
console.log('数据',state) console.log('数据', state)
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
:deep() { :deep() {
.uni-input-wrapper { .uni-input-wrapper {
width: 320rpx; width: 320rpx;
} }
.uni-easyinput__content-input { .uni-easyinput__content-input {
font-size: 28rpx; font-size: 28rpx;
height: 72rpx; height: 72rpx;
text-align: right !important; text-align: right !important;
padding-right: 0 !important; padding-right: 0 !important;
.uni-input-input { .uni-input-input {
font-weight: 500; font-weight: 500;
color: #333333; color: #333333;
font-size: 26rpx; font-size: 26rpx;
height: 32rpx; height: 32rpx;
margin-top: 4rpx; margin-top: 4rpx;
} }
} }
.uni-easyinput__content { .uni-easyinput__content {
display: flex !important; display: flex !important;
align-items: center !important; align-items: center !important;
justify-content: right !important; justify-content: right !important;
} }
} }
.score-img { .score-img {
width: 36rpx; width: 36rpx;
height: 36rpx; height: 36rpx;
margin: 0 4rpx; margin: 0 4rpx;
} }
.order-item { .order-item {
height: 80rpx; height: 80rpx;
.item-title { .item-title {
font-size: 28rpx; font-size: 28rpx;
font-weight: 400; font-weight: 400;
} }
.item-value { .item-value {
font-size: 28rpx; font-size: 28rpx;
font-weight: 500; font-weight: 500;
font-family: OPPOSANS; font-family: OPPOSANS;
} }
.text-disabled { .text-disabled {
color: #bbbbbb; color: #bbbbbb;
} }
.item-icon { .item-icon {
color: $dark-9; color: $dark-9;
} }
.remark-input { .remark-input {
text-align: right; text-align: right;
} }
.item-placeholder { .item-placeholder {
color: $dark-9; color: $dark-9;
font-size: 26rpx; font-size: 26rpx;
text-align: right; text-align: right;
} }
} }
.total-box-footer { .total-box-footer {
height: 90rpx; height: 90rpx;
.total-num { .total-num {
color: #333333; color: #333333;
font-family: OPPOSANS; font-family: OPPOSANS;
} }
} }
.footer-box { .footer-box {
height: 100rpx; height: 100rpx;
.submit-btn { .submit-btn {
width: 240rpx; width: 240rpx;
height: 70rpx; height: 70rpx;
font-size: 28rpx; font-size: 28rpx;
font-weight: 500; font-weight: 500;
.goto-pay-text { .goto-pay-text {
line-height: 28rpx; line-height: 28rpx;
} }
} }
.cancel-btn { .cancel-btn {
width: 240rpx; width: 240rpx;
height: 80rpx; height: 80rpx;
font-size: 26rpx; font-size: 26rpx;
background-color: #e5e5e5; background-color: #e5e5e5;
color: $dark-9; color: $dark-9;
} }
} }
.title { .title {
font-size: 36rpx; font-size: 36rpx;
font-weight: bold; font-weight: bold;
color: #333333; color: #333333;
} }
.subtitle { .subtitle {
font-size: 28rpx; font-size: 28rpx;
color: #999999; color: #999999;
} }
.cicon-checkbox { .cicon-checkbox {
font-size: 36rpx; font-size: 36rpx;
color: var(--ui-BG-Main); color: var(--ui-BG-Main);
} }
.cicon-box { .cicon-box {
font-size: 36rpx; font-size: 36rpx;
color: #999999; color: #999999;
} }
</style> </style>

View File

@ -1,495 +1,466 @@
<!-- 订单列表 --> <!-- 订单列表 -->
<template> <template>
<s-layout title="我的订单"> <s-layout title="我的订单">
<su-sticky bgColor="#fff"> <su-sticky bgColor="#fff">
<su-tabs <su-tabs :list="tabMaps" :scrollable="false" @change="onTabsChange" :current="state.currentTab" />
:list="tabMaps" </su-sticky>
:scrollable="false" <s-empty v-if="state.pagination.total === 0" icon="/static/order-empty.png" text="暂无订单" />
@change="onTabsChange" <view v-if="state.pagination.total > 0">
:current="state.currentTab" <view class="bg-white order-list-card-box ss-r-10 ss-m-t-14 ss-m-20" v-for="order in state.pagination.list"
/> :key="order.id" @tap="onOrderDetail(order.id)">
</su-sticky> <view class="order-card-header ss-flex ss-col-center ss-row-between ss-p-x-20">
<s-empty v-if="state.pagination.total === 0" icon="/static/order-empty.png" text="暂无订单" /> <view class="order-no">订单号{{ order.no }}</view>
<view v-if="state.pagination.total > 0"> <view class="order-state ss-font-26" :class="formatOrderColor(order)">
<view {{ formatOrderStatus(order) }}
class="bg-white order-list-card-box ss-r-10 ss-m-t-14 ss-m-20" </view>
v-for="order in state.pagination.list" </view>
:key="order.id" <view class="border-bottom" v-for="item in order.items" :key="item.id">
@tap="onOrderDetail(order.id)" <s-goods-item :img="item.picUrl" :title="item.spuName"
> :skuText="item.properties.map((property) => property.valueName).join(' ')" :price="item.price"
<view class="order-card-header ss-flex ss-col-center ss-row-between ss-p-x-20"> :num="item.count" />
<view class="order-no">订单号{{ order.no }}</view> </view>
<view class="order-state ss-font-26" :class="formatOrderColor(order)"> <view class="pay-box ss-m-t-30 ss-flex ss-row-right ss-p-r-20">
{{ formatOrderStatus(order) }} <view class="ss-flex ss-col-center">
</view> <view class="discounts-title pay-color"> {{ order.productCount }} 件商品,总金额:</view>
</view> <view class="discounts-money pay-color"> {{ fen2yuan(order.payPrice) }} </view>
<view class="border-bottom" v-for="item in order.items" :key="item.id"> </view>
<s-goods-item </view>
:img="item.picUrl" <view class="order-card-footer ss-flex ss-col-center ss-p-x-20"
:title="item.spuName" :class="order.buttons.length > 3 ? 'ss-row-between' : 'ss-row-right'">
:skuText="item.properties.map((property) => property.valueName).join(' ')" <view class="ss-flex ss-col-center">
:price="item.price" <button v-if="order.buttons.includes('combination') && order.status !== 0 && order.status !== 40" class="tool-btn ss-reset-button"
:num="item.count" @tap.stop="onOrderGroupon(order)">
/> 拼团详情
</view> </button>
<view class="pay-box ss-m-t-30 ss-flex ss-row-right ss-p-r-20"> <button v-if="order.buttons.length === 0" class="tool-btn ss-reset-button"
<view class="ss-flex ss-col-center"> @tap.stop="onOrderDetail(order.id)">
<view class="discounts-title pay-color" 查看详情
> {{ order.productCount }} 件商品,总金额:</view </button>
> <button v-if="order.buttons.includes('confirm')" class="tool-btn ss-reset-button"
<view class="discounts-money pay-color"> {{ fen2yuan(order.payPrice) }} </view> @tap.stop="onConfirm(order)">
</view> 确认收货
</view> </button>
<view <button v-if="order.buttons.includes('express')" class="tool-btn ss-reset-button"
class="order-card-footer ss-flex ss-col-center ss-p-x-20" @tap.stop="onExpress(order.id)">
:class="order.buttons.length > 3 ? 'ss-row-between' : 'ss-row-right'" 查看物流
> </button>
<view class="ss-flex ss-col-center"> <button v-if="order.buttons.includes('cancel')" class="tool-btn ss-reset-button"
<button @tap.stop="onCancel(order.id)">
v-if="order.buttons.includes('combination')" 取消订单
class="tool-btn ss-reset-button" </button>
@tap.stop="onOrderGroupon(order)" <button v-if="order.buttons.includes('comment')" class="tool-btn ss-reset-button"
> @tap.stop="onComment(order.id)">
拼团详情 评价
</button> </button>
<button <button v-if="order.buttons.includes('delete')" class="delete-btn ss-reset-button"
v-if="order.buttons.length === 0" @tap.stop="onDelete(order.id)">
class="tool-btn ss-reset-button" 删除订单
@tap.stop="onOrderDetail(order.id)" </button>
> <button v-if="order.buttons.includes('pay')"
查看详情 class="tool-btn ss-reset-button ui-BG-Main-Gradient" @tap.stop="onPay(order.payOrderId)">
</button> 继续支付
<button </button>
v-if="order.buttons.includes('confirm')" </view>
class="tool-btn ss-reset-button" </view>
@tap.stop="onConfirm(order)" </view>
> </view>
确认收货
</button>
<button
v-if="order.buttons.includes('express')"
class="tool-btn ss-reset-button"
@tap.stop="onExpress(order.id)"
>
查看物流
</button>
<button
v-if="order.buttons.includes('cancel')"
class="tool-btn ss-reset-button"
@tap.stop="onCancel(order.id)"
>
取消订单
</button>
<button
v-if="order.buttons.includes('comment')"
class="tool-btn ss-reset-button"
@tap.stop="onComment(order.id)"
>
评价
</button>
<button
v-if="order.buttons.includes('delete')"
class="delete-btn ss-reset-button"
@tap.stop="onDelete(order.id)"
>
删除订单
</button>
<button
v-if="order.buttons.includes('pay')"
class="tool-btn ss-reset-button ui-BG-Main-Gradient"
@tap.stop="onPay(order.payOrderId)"
>
继续支付
</button>
</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, onPullDownRefresh } from '@dcloudio/uni-app'; reactive
import { } from 'vue';
fen2yuan, import {
formatOrderColor, onLoad,
formatOrderStatus, onReachBottom,
handleOrderButtons, onPullDownRefresh
} from '@/sheep/hooks/useGoods'; } from '@dcloudio/uni-app';
import sheep from '@/sheep'; import {
import _ from 'lodash-es'; fen2yuan,
import { isEmpty } from 'lodash-es'; formatOrderColor,
import OrderApi from '@/sheep/api/trade/order'; formatOrderStatus,
import { resetPagination } from '@/sheep/util'; handleOrderButtons,
} from '@/sheep/hooks/useGoods';
import sheep from '@/sheep';
import _ from 'lodash-es';
import {
isEmpty
} from 'lodash-es';
import OrderApi from '@/sheep/api/trade/order';
import {
resetPagination
} from '@/sheep/util';
// //
const state = reactive({ const state = reactive({
currentTab: 0, // tabMaps currentTab: 0, // tabMaps
pagination: { pagination: {
list: [], list: [],
total: 0, total: 0,
pageNo: 1, pageNo: 1,
pageSize: 5, pageSize: 5,
}, },
loadStatus: '', loadStatus: '',
}); });
const tabMaps = [ const tabMaps = [{
{ name: '全部',
name: '全部', },
}, {
{ name: '待付款',
name: '待付款', value: 0,
value: 0, },
}, {
{ name: '待发货',
name: '待发货', value: 10,
value: 10, },
}, {
{ name: '待收货',
name: '待收货', value: 20,
value: 20, },
}, {
{ name: '待评价',
name: '待评价', value: 30,
value: 30, },
}, ];
];
// //
function onTabsChange(e) { function onTabsChange(e) {
if (state.currentTab === e.index) { if (state.currentTab === e.index) {
return; return;
} }
// //
resetPagination(state.pagination); resetPagination(state.pagination);
state.currentTab = e.index; state.currentTab = e.index;
getOrderList(); getOrderList();
} }
// //
function onOrderDetail(id) { function onOrderDetail(id) {
sheep.$router.go('/pages/order/detail', { sheep.$router.go('/pages/order/detail', {
id, id,
}); });
} }
// //
function onOrderGroupon(order) { function onOrderGroupon(order) {
sheep.$router.go('/pages/activity/groupon/detail', { sheep.$router.go('/pages/activity/groupon/detail', {
id: order.combinationRecordId, id: order.combinationRecordId,
}); });
} }
// //
function onPay(payOrderId) { function onPay(payOrderId) {
sheep.$router.go('/pages/pay/index', { sheep.$router.go('/pages/pay/index', {
id: payOrderId, id: payOrderId,
}); });
} }
// //
function onComment(id) { function onComment(id) {
sheep.$router.go('/pages/goods/comment/add', { sheep.$router.go('/pages/goods/comment/add', {
id, id,
}); });
} }
// TODO // TODO
async function onConfirm(order, ignore = false) { async function onConfirm(order, ignore = false) {
// //
// todo: // todo:
// 1.return // 1.return
// 2.mpConfirm,App.vueshow // 2.mpConfirm,App.vueshow
let isOpenBusinessView = true; let isOpenBusinessView = true;
if ( if (
sheep.$platform.name === 'WechatMiniProgram' && sheep.$platform.name === 'WechatMiniProgram' &&
!isEmpty(order.wechat_extra_data) && !isEmpty(order.wechat_extra_data) &&
isOpenBusinessView && isOpenBusinessView &&
!ignore !ignore
) { ) {
mpConfirm(order); mpConfirm(order);
return; return;
} }
// //
const { code } = await OrderApi.receiveOrder(order.id); const {
if (code === 0) { code
resetPagination(state.pagination); } = await OrderApi.receiveOrder(order.id);
await getOrderList(); if (code === 0) {
} resetPagination(state.pagination);
} await getOrderList();
}
}
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
// TODO // TODO
function mpConfirm(order) { function mpConfirm(order) {
if (!wx.openBusinessView) { if (!wx.openBusinessView) {
sheep.$helper.toast(`请升级微信版本`); sheep.$helper.toast(`请升级微信版本`);
return; return;
} }
wx.openBusinessView({ wx.openBusinessView({
businessType: 'weappOrderConfirm', businessType: 'weappOrderConfirm',
extraData: { extraData: {
merchant_id: '1481069012', merchant_id: '1481069012',
merchant_trade_no: order.wechat_extra_data.merchant_trade_no, merchant_trade_no: order.wechat_extra_data.merchant_trade_no,
transaction_id: order.wechat_extra_data.transaction_id, transaction_id: order.wechat_extra_data.transaction_id,
}, },
success(response) { success(response) {
console.log('success:', response); console.log('success:', response);
if (response.errMsg === 'openBusinessView:ok') { if (response.errMsg === 'openBusinessView:ok') {
if (response.extraData.status === 'success') { if (response.extraData.status === 'success') {
onConfirm(order, true); onConfirm(order, true);
} }
} }
}, },
fail(error) { fail(error) {
console.log('error:', error); console.log('error:', error);
}, },
complete(result) { complete(result) {
console.log('result:', result); console.log('result:', result);
}, },
}); });
} }
// #endif // #endif
// //
async function onExpress(id) { async function onExpress(id) {
sheep.$router.go('/pages/order/express/log', { sheep.$router.go('/pages/order/express/log', {
id, id,
}); });
} }
// //
async function onCancel(orderId) { async function onCancel(orderId) {
uni.showModal({ uni.showModal({
title: '提示', title: '提示',
content: '确定要取消订单吗?', content: '确定要取消订单吗?',
success: async function (res) { success: async function(res) {
if (!res.confirm) { if (!res.confirm) {
return; return;
} }
const { code } = await OrderApi.cancelOrder(orderId); const {
if (code === 0) { code
// } = await OrderApi.cancelOrder(orderId);
let index = state.pagination.list.findIndex((order) => order.id === orderId); if (code === 0) {
const orderInfo = state.pagination.list[index]; //
orderInfo.status = 40; let index = state.pagination.list.findIndex((order) => order.id === orderId);
handleOrderButtons(orderInfo); const orderInfo = state.pagination.list[index];
} orderInfo.status = 40;
}, handleOrderButtons(orderInfo);
}); }
} },
});
}
// //
function onDelete(orderId) { function onDelete(orderId) {
uni.showModal({ uni.showModal({
title: '提示', title: '提示',
content: '确定要删除订单吗?', content: '确定要删除订单吗?',
success: async function (res) { success: async function(res) {
if (res.confirm) { if (res.confirm) {
const { code } = await OrderApi.deleteOrder(orderId); const {
if (code === 0) { code
// } = await OrderApi.deleteOrder(orderId);
let index = state.pagination.list.findIndex((order) => order.id === orderId); if (code === 0) {
state.pagination.list.splice(index, 1); //
} let index = state.pagination.list.findIndex((order) => order.id === orderId);
} state.pagination.list.splice(index, 1);
}, }
}); }
} },
});
}
// //
async function getOrderList() { async function getOrderList() {
state.loadStatus = 'loading'; state.loadStatus = 'loading';
let { code, data } = await OrderApi.getOrderPage({ let {
pageNo: state.pagination.pageNo, code,
pageSize: state.pagination.pageSize, data
status: tabMaps[state.currentTab].value, } = await OrderApi.getOrderPage({
commentStatus: tabMaps[state.currentTab].value === 30 ? false : null, pageNo: state.pagination.pageNo,
}); pageSize: state.pagination.pageSize,
if (code !== 0) { status: tabMaps[state.currentTab].value,
return; commentStatus: tabMaps[state.currentTab].value === 30 ? false : null,
} });
data.list.forEach((order) => handleOrderButtons(order)); if (code !== 0) {
state.pagination.list = _.concat(state.pagination.list, data.list); return;
state.pagination.total = data.total; }
state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore'; data.list.forEach((order) => handleOrderButtons(order));
} 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';
}
onLoad(async (options) => { onLoad(async (options) => {
if (options.type) { if (options.type) {
state.currentTab = options.type; state.currentTab = options.type;
} }
await getOrderList(); await getOrderList();
}); });
// //
function loadMore() { function loadMore() {
if (state.loadStatus === 'noMore') { if (state.loadStatus === 'noMore') {
return; return;
} }
state.pagination.pageNo++; state.pagination.pageNo++;
getOrderList(); getOrderList();
} }
// //
onReachBottom(() => { onReachBottom(() => {
loadMore(); loadMore();
}); });
// //
onPullDownRefresh(() => { onPullDownRefresh(() => {
resetPagination(state.pagination); resetPagination(state.pagination);
getOrderList(); getOrderList();
setTimeout(function () { setTimeout(function() {
uni.stopPullDownRefresh(); uni.stopPullDownRefresh();
}, 800); }, 800);
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.score-img { .score-img {
width: 36rpx; width: 36rpx;
height: 36rpx; height: 36rpx;
margin: 0 4rpx; margin: 0 4rpx;
} }
.tool-btn { .tool-btn {
width: 160rpx; width: 160rpx;
height: 60rpx; height: 60rpx;
background: #f6f6f6; background: #f6f6f6;
font-size: 26rpx; font-size: 26rpx;
border-radius: 30rpx; border-radius: 30rpx;
margin-right: 10rpx; margin-right: 10rpx;
&:last-of-type { &:last-of-type {
margin-right: 0; margin-right: 0;
} }
} }
.delete-btn { .delete-btn {
width: 160rpx; width: 160rpx;
height: 56rpx; height: 56rpx;
color: #ff3000; color: #ff3000;
background: #fee; background: #fee;
border-radius: 28rpx; border-radius: 28rpx;
font-size: 26rpx; font-size: 26rpx;
margin-right: 10rpx; margin-right: 10rpx;
line-height: normal; line-height: normal;
&:last-of-type { &:last-of-type {
margin-right: 0; margin-right: 0;
} }
} }
.apply-btn { .apply-btn {
width: 140rpx; width: 140rpx;
height: 50rpx; height: 50rpx;
border-radius: 25rpx; border-radius: 25rpx;
font-size: 24rpx; font-size: 24rpx;
border: 2rpx solid #dcdcdc; border: 2rpx solid #dcdcdc;
line-height: normal; line-height: normal;
margin-left: 16rpx; margin-left: 16rpx;
} }
.swiper-box { .swiper-box {
flex: 1; flex: 1;
.swiper-item { .swiper-item {
height: 100%; height: 100%;
width: 100%; width: 100%;
} }
} }
.order-list-card-box { .order-list-card-box {
.order-card-header { .order-card-header {
height: 80rpx; height: 80rpx;
.order-no { .order-no {
font-size: 26rpx; font-size: 26rpx;
font-weight: 500; font-weight: 500;
} }
.order-state { .order-state {}
} }
}
.pay-box { .pay-box {
.discounts-title { .discounts-title {
font-size: 24rpx; font-size: 24rpx;
line-height: normal; line-height: normal;
color: #999999; color: #999999;
} }
.discounts-money { .discounts-money {
font-size: 24rpx; font-size: 24rpx;
line-height: normal; line-height: normal;
color: #999; color: #999;
font-family: OPPOSANS; font-family: OPPOSANS;
} }
.pay-color { .pay-color {
color: #333; color: #333;
} }
} }
.order-card-footer { .order-card-footer {
height: 100rpx; height: 100rpx;
.more-item-box { .more-item-box {
padding: 20rpx; padding: 20rpx;
.more-item { .more-item {
height: 60rpx; height: 60rpx;
.title { .title {
font-size: 26rpx; font-size: 26rpx;
} }
} }
} }
.more-btn { .more-btn {
color: $dark-9; color: $dark-9;
font-size: 24rpx; font-size: 24rpx;
} }
.content { .content {
width: 154rpx; width: 154rpx;
color: #333333; color: #333333;
font-size: 26rpx; font-size: 26rpx;
font-weight: 500; font-weight: 500;
} }
} }
} }
:deep(.uni-tooltip-popup) { :deep(.uni-tooltip-popup) {
background: var(--ui-BG); background: var(--ui-BG);
} }
.warning-color { .warning-color {
color: #faad14; color: #faad14;
} }
.danger-color { .danger-color {
color: #ff3000; color: #ff3000;
} }
.success-color { .success-color {
color: #52c41a; color: #52c41a;
} }
.info-color { .info-color {
color: #999999; color: #999999;
} }
</style> </style>

View File

@ -3,7 +3,7 @@
<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>
<view v-if="state.activityMap.length"> <view v-if="state.activityMap[state.activityInfo[0]?.id]?.reduc">
<view class="titleLi">促销</view> <view class="titleLi">促销</view>
<scroll-view class="model-content" scroll-y :scroll-with-animation="false" :enable-back-to-top="true"> <scroll-view class="model-content" scroll-y :scroll-with-animation="false" :enable-back-to-top="true">
<view class="actBox"> <view class="actBox">

View File

@ -124,6 +124,7 @@
// //
function onAddCart() { function onAddCart() {
console.log('购物车',state.selectedSku)
if (state.selectedSku.id <= 0) { if (state.selectedSku.id <= 0) {
sheep.$helper.toast('请选择规格'); sheep.$helper.toast('请选择规格');
return; return;

View File

@ -100,6 +100,7 @@ export const WxaSubscribeTemplate = {
export const getTimeStatusEnum = (startTime, endTime) => { export const getTimeStatusEnum = (startTime, endTime) => {
const now = dayjs(); const now = dayjs();
console.log('处理的数据',now,startTime,endTime)
if (now.isBefore(startTime)) { if (now.isBefore(startTime)) {
return TimeStatusEnum.WAIT_START; return TimeStatusEnum.WAIT_START;
} else if (now.isAfter(endTime)) { } else if (now.isAfter(endTime)) {