调整点餐页面样式,增加限时折扣倒计时

This commit is contained in:
2025-12-10 13:59:29 +08:00
parent 1b8fdd16a1
commit a95fa69c62
4 changed files with 226 additions and 66 deletions

View File

@@ -17,7 +17,7 @@
</view>
</view> -->
<scroll-view scroll-y class="scroll-view">
<view class="list-wrap">
<view class="list-wrap" :class="[nextFullAmountActivty?'pb-20': '']">
<view v-if="cartList.length > 0">
<view class="ShoppingCart flex-between">
<view> 购物车 </view>
@@ -142,6 +142,9 @@ import * as orderUtils from "@/utils/order-utils.js";
const emits = defineEmits(["customevent", "close", "clickcancelOrder"]);
const props = defineProps({
nextFullAmountActivty: {
type: Object,
},
cartList: {
type: Array,
},
@@ -361,7 +364,9 @@ const cartclear = () => {
.list-wrap {
padding: 0 28rpx;
&.pb-20{
padding-bottom: 20px;
}
.ShoppingCart {
font-size: 30rpx;
text-align: left;

View File

@@ -3,15 +3,39 @@
<Nav />
<!-- 顶部面板 -->
<view class="top--panel" :class="{ grayscale: !isBusinessTime }">
<image
class="panelimgbackground"
:src="
shopExtend
? shopExtend.value
: 'https://czg-qr-order.oss-cn-beijing.aliyuncs.com/shopDetails/topBanner.png'
"
mode="aspectFill"
></image>
<template v-if="shopExtend">
<image
class="panelimgbackground"
:src="
shopExtend
? shopExtend.value
: 'https://czg-qr-order.oss-cn-beijing.aliyuncs.com/shopDetails/topBanner.png'
"
mode="aspectFill"
v-if="!isJsonArrayString(shopExtend.value)"
></image>
<swiper
class="panelimgbackground"
autoplay
indicator-dots
circular
v-else
>
<swiper-item
v-for="(item, index) in JSON.parse(shopExtend.value)"
:key="index"
>
<image :src="item" mode="aspectFill"></image>
</swiper-item>
</swiper>
</template>
<template v-else>
<image
class="panelimgbackground"
src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/shopDetails/topBanner.png"
mode="aspectFill"
></image>
</template>
<view class="panelone">
<text>
{{ shopInfo.shopName }}
@@ -19,10 +43,10 @@
<view class="paneltow">距离您{{ distance }}</view>
<!-- <up-icon name="arrow-right" color="#999999" size="14"></up-icon> -->
</view>
<view class="new-user-discount u-font-28">
<view class="new-user-discount u-font-28" v-if="newUserDiscount">
<text class="">新客立减¥</text>
<text class="u-font-32">10.00</text>
<text class="u-m-l-60">新客可随机减免金额</text>
<text class="u-font-32">{{ newUserDiscount.amount }}</text>
<!-- <text class="u-m-l-60">新客可随机减免金额</text> -->
</view>
<view class="panelthere flex-between">
<view class="paneltheretext">
@@ -59,7 +83,7 @@
:key="index"
>
<!-- <view class="limitDiscount" v-if="showLimitDiscount(item)"
>限时折扣19:45</view
>限时折扣{{limitDiscountCountdown}}</view
> -->
<view class="relative">
@@ -70,7 +94,7 @@
mode="aspectFill"
></image>
<view class="limitDiscount" v-if="item.is_time_discount"
>限时折扣19:45</view
>限时折扣{{ limitDiscountCountdown }}</view
>
</view>
@@ -343,7 +367,7 @@
:lazy-load="true"
></image>
<view class="limitDiscount" v-if="item1.is_time_discount"
>限时折扣19:45</view
>限时折扣{{ limitDiscountCountdown }}</view
>
</view>
@@ -553,6 +577,7 @@
:orderinfo="orderinfo"
@clickcancelOrder="clickcancelOrder"
v-if="cartLists_count > 0"
:nextFullAmountActivty="nextFullAmountActivty"
></shoppingCartes>
<!-- 显示购物车栏 -->
@@ -575,7 +600,11 @@
</view>
<text class="i">¥</text>
<text class="num">{{ totalPrices }}</text>
<text class="num">{{ actualPrice }}</text>
<text class="allDiscountMoney" v-if="allDiscountMoney * 1 > 0"
>共减¥{{ allDiscountMoney }}</text
>
</view>
<view
class="btn"
@@ -594,14 +623,20 @@
>
</view>
</view>
<!-- 满减活动 -->
<view class="fullAmount-activity">
<text>再买</text>
<text class="price">¥7</text>
<text></text>
<text>可在减</text>
<text class="price">¥6</text>
</view>
<!-- 满减活动 -->
<view class="fullAmount-activity" v-if="nextFullAmountActivty">
<text>再买</text>
<text class="price"
>¥{{
BigNumber(nextFullAmountActivty.fullAmount)
.minus(totalPrices * 1)
.toFixed(2)
}}</text
>
<text></text>
<text>可再减</text>
<text class="price">¥{{ nextFullAmountActivty.discountAmount }}</text>
</view>
</view>
<!-- 规格 -->
@@ -741,7 +776,7 @@
<view class="shop_bottom">
<view class="flex-between">
<view
class="price"
class="price price-sku"
v-if="
specifications.item.type != 'package' &&
specifications.item.result
@@ -773,7 +808,7 @@
}}{{ specifications.item.result.unitName }}起点」</text
>
</view>
<view class="price" v-else>
<view class="price price-package" v-else>
<text class="i">¥</text>
<view class="num">
<GoodsPrice
@@ -949,6 +984,10 @@ import xbSwiperPreview from "@/components/xb-swiper-preview/index.vue";
//价格计算辅助函数
// import * as limitUtils from '@/utils/order-utils.js';
import { limitUtils } from "ysk-utils";
// 满减活动api
import * as discountActivityApi from "@/common/api/market/discountActivity";
import BigNumber from "bignumber.js";
import { consumeDiscount } from "@/common/api/market/index.js";
@@ -987,7 +1026,7 @@ import Loading from "@/components/Loading.vue";
import dayjs from "dayjs";
import isBetween from "dayjs/plugin/isBetween";
dayjs.extend(isBetween);
import { filterNumberInput } from "@/utils/util.js";
import { filterNumberInput, isJsonArrayString } from "@/utils/util.js";
import { APIproductqueryShop } from "@/common/api/member.js";
import { getDistance } from "@/utils/address.js";
@@ -1108,10 +1147,10 @@ const callChildMethod = () => {
// console.log('shopExtend', shopExtend);
// 分步取值 + 每层兜底,避免某一环不存在导致 undefined
const shopExtendShopTable = uni.cache.get('shopTable') || {}; // 兜底空对象
const shopExtendShopTable = uni.cache.get("shopTable") || {}; // 兜底空对象
const shopExtendMap = shopExtendShopTable.shopExtendMap || {}; // 兜底空对象
// 最终声明:即使 shopinfo_bg 不存在,也兜底为空字符串/默认值
const shopExtend = ref(shopExtendMap.shopinfo_bg || '');
const shopExtend = ref(shopExtendMap.shopinfo_bg || "");
// try {
// const shopExtend = uni.cache.get('shopTable').shopExtendMap.shopinfo_bg;
@@ -1426,6 +1465,10 @@ const shopCart = async (i) => {
// singleclick(specifications.item, i);
// return;
// }
if(specifications.item.result==='kong'){
//没有满足可添加或者编辑的规格
return
}
if (i == "-") {
if (!res && shopCartNumber.value == specifications.item.suitNum) {
uni.showToast({
@@ -1438,7 +1481,6 @@ const shopCart = async (i) => {
}
} else {
if (!res && shopCartNumber.value < 1) {
console.log(res, specifications);
if (specifications.type == "sku") {
shopCartNumber.value = parseFloat(specifications.item.result.suitNum);
} else {
@@ -2282,6 +2324,26 @@ const totalPrices = computed(() => {
return parseFloat(cart.toFixed(2));
});
//全部优惠券金额
const allDiscountMoney=computed(()=>{
let discountMoney=0
// 新客立减
if (newUserDiscount.value && newUserDiscount.value.discountAmount) {
discountMoney+=newUserDiscount.value.discountAmount
}
// 满减活动
if (fullAmountActivty.value && fullAmountActivty.value.discountAmount) {
discountMoney+=fullAmountActivty.value.discountAmount
}
return discountMoney.toFixed(2)
})
// 计算实际金额(购物车商品费用-新客立减-满减活动)
const actualPrice = computed(() => {
let price = BigNumber(totalPrices.value*1).minus(allDiscountMoney.value*1).toFixed(2);
return price<=0?0:price;
});
// 计算购物车商品总数量
const cartLists_count = computed(() => {
const combinedOrderInfo = combineOrderInfoDetailMap(orderinfo.value);
@@ -2628,6 +2690,43 @@ onLoad(async (e) => {
});
const limitTimeDiscountRes = ref(null);
const nowTime=ref(getEndTimeInSeconds(dayjs().format('HH:mm')) )
let timer=setInterval(() => {
nowTime.value=getEndTimeInSeconds(dayjs().format('HH:mm'))
}, 1000);
function getEndTimeInSeconds(endTime){
const [hour, minute] = endTime.split(':').map(Number);
return hour * 60 * 60 + minute * 60;
}
// 将秒再转为hh::mm
function secondsToHHMM(seconds) {
const hours = Math.floor(seconds / 60 / 60);
const minutes = Math.floor(seconds / 60) % 60;
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
}
const limitDiscountCountdown=computed(()=>{
if(!limitTimeDiscountRes.value&&!limitTimeDiscountRes.value.id){
return ''
}
if(limitTimeDiscountRes.value.useTimeType!="custom"){
return ''
}
//根据当前时间和限时折扣的结束时间计算倒计时,结束时间是hh:mm,将hh:mm转换为时间多少秒然后再减去当前时间就得到了倒计时
const endTime=getEndTimeInSeconds(limitTimeDiscountRes.value.useEndTime)
const countdown=endTime-nowTime.value
if(countdown<=0){
return ''
}
return secondsToHHMM(countdown)
})
function showLimitDiscount(item) {
if (!cartStore.limitTimeDiscount || !cartStore.limitTimeDiscount.id) {
@@ -2695,11 +2794,53 @@ async function getNewUserDiscount() {
let res = await consumeDiscount({
shopId: uni.cache.get("shopId"),
});
if (res) {
if (res&&typeof res == "object") {
newUserDiscount.value = res;
}
}
const fullAmountActivity = ref(null);
//获取满减活动
async function getDiscountActivity() {
const res = await discountActivityApi.config({
shopId: uni.cache.get("shopId"),
});
if (res) {
fullAmountActivity.value = res;
}
}
//返回当前满足的满减的活动
const fullAmountActivty = computed(() => {
if (!fullAmountActivity.value) {
return null;
}
//下一个满足满减的
let fullAmount = null;
for (let item of fullAmountActivity.value.thresholds) {
if (totalPrices.value * 1 >= item.fullAmount) {
fullAmount = item;
break;
}
}
return fullAmount;
});
//返回下一个满减活动
const nextFullAmountActivty = computed(() => {
if (!fullAmountActivity.value) {
return null;
}
//下一个满足满减的
let nextFullAmount = null;
for (let item of fullAmountActivity.value.thresholds) {
if (totalPrices.value * 1 < item.fullAmount) {
nextFullAmount = item;
break;
}
}
return nextFullAmount;
});
const oldOrder = ref(null);
@@ -2712,7 +2853,10 @@ onMounted(async () => {
// 获取页面参数
const options = currentPage.options;
console.log("onMounted", options);
//新客立减
getNewUserDiscount();
// 满减活动
getDiscountActivity();
let res = await APIhistoryOrder({
tableCode: uni.cache.get("tableCode"),
});
@@ -3599,24 +3743,24 @@ function toHistory() {
.cart-wrap {
width: 100%;
padding: 0 20rpx;
padding: 22rpx 54rpx;
box-sizing: border-box;
position: fixed;
bottom: 40rpx;
bottom: 0;
left: 0;
right: 0;
z-index: 99;
padding-bottom: calc(env(safe-area-inset-bottom) + 1px);
background: #ffffff;
.cart-content {
display: flex;
align-items: center;
height: 128rpx;
background: #ffffff;
box-shadow: 0rpx 0rpx 20rpx 2rpx rgba(0, 0, 0, 0.15);
border-radius: 58rpx;
padding: 0 36rpx;
// height: 128rpx;
// padding: 0 36rpx;
box-sizing: border-box;
position: relative;
z-index: 99;
position: relative;
z-index: 99;
.left {
flex: 1;
display: flex;
@@ -3654,7 +3798,7 @@ function toHistory() {
}
.i {
font-size: 20upx;
font-size: 28rpx;
position: relative;
top: 4upx;
margin-left: 64rpx;
@@ -3668,7 +3812,6 @@ function toHistory() {
.btn {
height: 100%;
width: 40%;
display: flex;
align-items: center;
justify-content: flex-end;
@@ -3818,17 +3961,23 @@ function toHistory() {
font-weight: 700;
padding-left: 20rpx;
}
.fullAmount-activity{
position: absolute;
bottom: 100%;
left: 0;
font-size: 28rpx;
right: 0;
color: #666666;
background: linear-gradient(90deg, #FFDFE9 0%, #FEF4EA 100%);
padding: 8rpx 78rpx 8rpx 42rpx;
.price{
color: #ff1c1c;
}
.fullAmount-activity {
position: absolute;
bottom: 100%;
left: 0;
font-size: 28rpx;
right: 0;
color: #666666;
background: linear-gradient(90deg, #ffdfe9 0%, #fef4ea 100%);
padding: 8rpx 78rpx 8rpx 42rpx;
.price {
color: #ff1c1c;
}
}
.allDiscountMoney {
color: #ff1c1c;
font-size: 12px;
margin-left: 20rpx;
}
</style>

View File

@@ -31,6 +31,8 @@ declare global {
const onHide: typeof import('@dcloudio/uni-app')['onHide']
const onLoad: typeof import('@dcloudio/uni-app')['onLoad']
const onMounted: typeof import('vue')['onMounted']
const onPageScroll: typeof import('@dcloudio/uni-app')['onPageScroll']
const onReady: typeof import('@dcloudio/uni-app')['onReady']
const onRenderTracked: typeof import('vue')['onRenderTracked']
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
const onScopeDispose: typeof import('vue')['onScopeDispose']

View File

@@ -7,20 +7,24 @@ module.exports = defineConfig({
plugins: [
uni(),
AutoImport({
include: [
/\.js$/,
/\.vue$/, /\.vue\?vue/
],
include: [/\.js$/, /\.vue$/, /\.vue\?vue/],
imports: [
"vue",
{
"@dcloudio/uni-app": [
"onLoad", "onShow", "onHide", "onUnload",
"uni.request", "uni.navigateTo", "uni.showToast"
]
}
"onLoad",
"onShow",
"onHide",
"onUnload",
"onReady",
"onPageScroll",
"uni.request",
"uni.navigateTo",
"uni.showToast",
],
},
],
dts: "src/auto-imports.d.ts"
dts: "src/auto-imports.d.ts",
}),
],
server: {
@@ -34,4 +38,4 @@ module.exports = defineConfig({
},
},
},
});
});