You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

2581 lines
66 KiB

<template>
<!-- 代买饭页 -->
<view class="page1" :class="{'store-group-checkout': isStoreGroupOrder}">
<view class="title">
<view class="title-sreach">
<view class="back-btn" @tap="back" :style="{'top': menuButtonInfo.top +'px'}">
<uni-icons type="left" size="28"></uni-icons>
</view>
</view>
<view class="store-hero-effect" v-if="isStoreGroupOrder">
<view class="store-orb orb-a"></view>
<view class="store-orb orb-b"></view>
<view class="store-hero-copy">
<view class="store-hero-badge">团购到店</view>
<view class="store-hero-title">约上同学一起省</view>
<view class="store-hero-sub">支付后到店核销,拼成更划算</view>
</view>
<view class="store-verify-card">
<view class="verify-icon">核</view>
<view>
<view class="verify-title">到店核销</view>
<view class="verify-sub">无需配送</view>
</view>
</view>
<view class="store-float-tag tag-a">拼团价</view>
<view class="store-float-tag tag-b">同校热拼</view>
</view>
</view>
<view class="tab-wrap" v-if="!isStoreGroupOrder">
<view class="tab1" v-if="isPaotui">
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/6b3a4d4c61ee42feb29e69d6fcfd2c1e.png" alt=""
class="tab-bg" />
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/1cbed0734a154a70b75cb84a811bd0b7.png" alt="" />
<view class="tab-hit-area">
<view class="tab-hit-item"></view>
<view class="tab-hit-item" @tap="isPaotui=!isPaotui"></view>
</view>
</view>
<view class="tab1" v-else>
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/3b98dfb370eb4ddcb942b7942dedced2.png" alt=""
class="tab-bg" />
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/82627e6cedcf409a932d6afaafa19a4b.png" alt=""
class="tab-bg" />
<view class="tab-hit-area">
<view class="tab-hit-item" @tap="isPaotui=!isPaotui"></view>
<view class="tab-hit-item"></view>
</view>
</view>
</view>
<view class="ziqu-box" v-if="isPaotui==false">
<view class="ziqu-xuanfu">
{{isStoreGroupOrder ? '到店信息' : '取餐信息'}}
</view>
<view class="ziqu-address">
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/e13c675ffd4547d0b271900902ffea66.png" alt="" />
<view class="ziqu-text">
{{isStoreGroupOrder ? '到店地址' : '地址'}}:{{shopItem.shopAddress || ''}}
</view>
</view>
</view>
<view class="address-box" v-if="isPaotui">
<view class="address-empty" v-if="!formData.address" @tap="openAddressBook">
<text>请选择收货地址</text>
<uni-icons type="right" size="16" color="#0b9b73"></uni-icons>
</view>
<view v-else class="address-content">
<view class="address-main" @tap="openAddressBook">
{{formData.address.areaName || ''}}{{formData.address.floor ? formData.address.floor + '层' : ''}}{{formData.address.roomNum || ''}}
{{formData.address.receiverName || ''}}
</view>
<view class="address-change" @tap.stop="openAddressBook">
更换地址 <uni-icons type="right" size="13" color="#0b9b73"></uni-icons>
</view>
</view>
</view>
<view class="time-box" v-if="isPaotui">
<view class="time1" @tap="checkTime(true)"
:class="{'time1-active': formData.isImmediately}">
<view class="time-title">
立即送出
</view>
<view class="time-desc">
预计{{immediateTimeStr}}送达
</view>
</view>
<view class="time1" @tap="checkTime(false)"
:class="{'time1-active': formData.isImmediately==false}">
<view class="time-title">
预约配送
</view>
<view>
<view class="time-desc" v-if="formData.isImmediately!=true&&formData.deliveryTime!=''">
{{formData.deliveryTime}}
</view>
<view class="time-desc" v-else>
选择时间 >
</view>
</view>
</view>
</view>
<view class="delivery-card" v-if="isPaotui">
<view class="delivery-head">
<view class="delivery-title">
配送员
</view>
<view class="delivery-desc">
指定配送员,如配送员拒绝接单或者下线,订单进入抢单大厅
</view>
<view class="delivery-desc">
不指定配送员超过10分钟没有人接单,会发送短信通知
</view>
</view>
<view class="delivery-options">
<view class="delivery-option">
<view class="delivery-choice">
<view class="radio-check" v-if="selected === 'buzhiding'">
<uni-icons type="checkmarkempty" size="12"></uni-icons>
</view>
<view class="radio-no-check" @tap="checkVoucher('buzhiding')" v-else></view>
不指定
</view>
<view class="commission-input" v-if="selected === 'buzhiding'">
<text>佣金 ¥</text>
<input type="digit" v-model="customCommission" placeholder="金额" />
</view>
</view>
<view class="delivery-option">
<view class="delivery-choice">
<view class="radio-check" v-if="selected === 'zhiding'">
<uni-icons type="checkmarkempty" size="12"></uni-icons>
</view>
<view class="radio-no-check" @tap="checkVoucher('zhiding')" v-else></view>
指定配送员
</view>
<view class="worker-entry" @tap="goDetail">
{{ assignedWorker ? assignedWorker.workerName + ' ' + assignedWorker.mobile : '配送员' }}
<uni-icons type="right" size="12"></uni-icons>
</view>
</view>
<view class="floor-fee-tip" v-if="highFloorFeeCalc > 0">
<uni-icons type="info" size="14" color="#ff5722"></uni-icons>
因您的收货楼层在3楼以上,将额外收取配送费 ¥{{highFloorFeeCalc}}
</view>
</view>
</view>
<view class="box1">
<view class="shop-title">
{{shopItem.shopName || '未知道商家'}}
</view>
<block v-if="!isGroupBuy">
<view class="goods-card"
v-for="(cartItem, index) in cartItems" :key="index">
<view class="goods-img">
<img :src="cartItem.item.productPicture" alt="">
</view>
<view class="goods-content">
<view class="goods-name">
{{cartItem.item.productName}}
</view>
<view class="goods-content-center" v-if="cartItem.specs">
<view class="goods-deal1">
{{getSpecDisplayString(cartItem.specs)}}
</view>
</view>
<view class="goods-content-bottom">
<view class="goods-count">
X{{cartItem.quantity}}
</view>
<view class="pintuan-left-price">
¥{{cartItem.price}}
</view>
</view>
</view>
</view>
</block>
<block v-else>
<view class="goods-card"
v-if="groupItem">
<view class="goods-img">
<img :src="groupItem.item.productPicture" alt="">
</view>
<view class="goods-content">
<view class="goods-name">
{{groupItem.item.productName}}
</view>
<view class="goods-content-center" v-if="groupItem.specs">
<view class="goods-deal1">
{{getSpecDisplayString(groupItem.specs)}}
</view>
</view>
<view class="goods-content-bottom">
<view class="goods-count">
X1
</view>
<view class="pintuan-left-price">
<view class="group-price-tag">
<text>拼团</text>
<text style="color: red;">¥{{groupItem.groupRule.groupPrice}}</text>
</view>
</view>
</view>
</view>
</view>
<block v-if="groupItem && groupItem.item.moreBuyData">
<view class="goods-card" v-for="(cartItem, index) in groupItem.item.moreBuyData" :key="index">
<view class="goods-img">
<img :src="cartItem.productPicture" alt="">
</view>
<view class="goods-content">
<view class="goods-name">
{{cartItem.productName}}
</view>
<view class="goods-content-center" v-if="cartItem.specs">
<view class="goods-deal1">
{{getSpecDisplayString(cartItem.specs)}}
</view>
</view>
<view class="goods-content-bottom">
<view class="goods-count">
X{{cartItem.quantity}}
</view>
<view class="pintuan-left-price">
¥{{cartItem.attributeListPrice | sliceMsg}}
</view>
</view>
</view>
</view>
</block>
</block>
<view class="fee-list">
<view class="fee-row" v-if="isPaotui">
<view class="fee-label">
打包费
</view>
<view class="fee-value">
¥{{packageFee.toFixed(2)}}
</view>
</view>
<view class="fee-row" v-if="isPaotui">
<view class="fee-label">
配送费 <text class="fee-tip" v-if="isFaceToFace">(均摊 | 如超过2人,每多一人配送费总额增加0.5)</text>
</view>
<view class="fee-value">
¥{{deliveryFeeCalc.toFixed(2)}}
</view>
</view>
<view class="fee-row" v-if="isPaotui ==false && !isStoreGroupOrder">
<view class="fee-label" style="color: #ff5722;font-size: 24rpx;padding: 14rpx 0 18rpx;">
立即出餐-(拼团单,拼团成功后立即出餐)
</view>
<view class="fee-value">
<view :class="nowMake ? 'radio-check' : 'radio-no-check'">
<uni-icons type="checkmarkempty" @tap="nowMakeMethod" size="12"></uni-icons>
</view>
</view>
</view>
<view class="fee-row" v-if="isPaotui == false && !isStoreGroupOrder">
<view class="fee-label">
用餐方式
</view>
<view class="pack-options">
<view class="pack-option" @tap="isPack = 0">
<view :class="isPack === 0 ? 'radio-check' : 'radio-no-check'">
<uni-icons v-if="isPack === 0" type="checkmarkempty" size="12"></uni-icons>
</view>
堂食
</view>
<view class="pack-option" @tap="isPack = 1">
<view :class="isPack === 1 ? 'radio-check' : 'radio-no-check'">
<uni-icons v-if="isPack === 1" type="checkmarkempty" size="12"></uni-icons>
</view>
打包
</view>
</view>
</view>
<view class="fee-row">
<view class="fee-label">
备注
</view>
<view class="remark-box">
<input type="text" v-model="remark" placeholder="口味、餐具等备注" />
</view>
</view>
</view>
<view class="coupon-row" @tap="openCouponPopup">
<view class="coupon-label">
优惠券
</view>
<view class="coupon-discount" v-if="selectedCoupon">
-¥{{selectedCoupon.discountAmount.toFixed(2)}}
</view>
<view class="coupon-available" v-else-if="availableCoupons.length > 0">
有 {{availableCoupons.length}} 张可用
</view>
<view class="coupon-empty" v-else>
无可用券
</view>
<uni-icons type="right" size="14" color="#999" style="margin-left:10rpx;"></uni-icons>
</view>
<view class="total-row">
<view class="total-label">
合计
</view>
<view class="total-price">
¥{{totalAmountCalc.toFixed(2)}}
</view>
</view>
<view class="bottom-placeholder"></view>
<view class="buy-bottom">
<view class="bottom-btn" @tap="submitPay">
<image class="pay-btn-gif" src="/static/images/img/loading.gif" mode="aspectFit"></image>
<text>{{isStoreGroupOrder ? '立即支付-到店核销' : ('立即支付' + (nowMake && isPaotui == false ? '-即刻出餐' : ''))}}</text>
</view>
</view>
</view>
<!-- 地址簿弹出层 -->
<uni-popup ref="bookPopup" background-color="#fff">
<view class="book-popup-content">
<address-list @selectAddress="handleSelectAddress" @syncAddress="handleSyncAddress"
@close="closeAddressBook"></address-list>
</view>
</uni-popup>
<!-- 警告弹出层 -->
<uni-popup ref="warnPopup" background-color="#fff">
<view class="warnImg">
<img v-if="warnPopup == 'shdz'" @tap="$refs.warnPopup.close()"
src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/4996043b3987401794b974d359429b8e.png"
alt="填写收货地址" style="width:600rpx;height:740rpx;" />
<img v-if="warnPopup == 'psyj'" @tap="$refs.warnPopup.close()"
src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/001cf760048b4718bdccd55085bef601.png"
alt="填写配送佣金" style="width:600rpx;height:740rpx;" />
<img v-if="warnPopup == 'psy'" @tap="$refs.warnPopup.close()"
src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/e10ad77ca478413a9c53918750ecb932.png"
alt="指定配送员" style="width:600rpx;height:740rpx;" />
</view>
</uni-popup>
<!-- 支付弹出层 -->
<uni-popup ref="payPopup" background-color="#fff">
<view class="pay-popup">
<view class="content">
<view class="box1">
<view style="display: flex;align-items: center;justify-content: center;height: 70rpx;">
支付剩余时间
<uni-countdown :show-day="false" :hour="00" :minute="59" :second="59" />
</view>
<view
style="height: 90rpx;line-height: 90rpx;text-align: center;font-weight: 700;font-size: 30rpx;">
¥<text
style="font-size: 60rpx;">{{backendTotalAmount ? backendTotalAmount.toFixed(2) : totalAmountCalc.toFixed(2)}}</text>
</view>
<view style="height: 40rpx;text-align: center;color: red;" v-if="isGroupBuy">
若拼团失败,将会为您自动退款
</view>
</view>
<view class="box1" style="display: flex;padding: 40rpx;">
<view style="flex: 1;">
<view style="height: 42rpx;line-height: 42rpx;display: flex;">
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/4c8e0cc311db4d38ab43e019673c4b8c.png"
alt="" style="width: 42rpx;height: 42rpx;margin-right: 20rpx;" />
<text style="font-size: 30rpx;font-weight: 700;">微信支付</text>
</view>
<view style="text-align: right;margin-left: 60rpx;color: #777;width: 146rpx;">
使用微信支付
</view>
</view>
<view style="width: 36rpx;padding-top: 20rpx;">
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/02bff7edc4e04caaa1868955ff684f1f.png"
alt="" style="width: 36rpx;height: 36rpx;" />
</view>
</view>
<view class="btn" @tap="wxPayment">
确认付款
</view>
</view>
</view>
</uni-popup>
<!-- 拼团分享弹出层 -->
<uni-popup ref="pintuanPopup" background-color="#fff" @change="onPintuanPopupChange">
<view class="pintuan-popup">
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/ecd00dab1c9c44198d765bc08bc1bd71.png" alt=""
style="position: absolute;top: 0;right: 0;width: 240rpx;height: 180rpx;" @tap="$refs.pintuanPopup.close()">
<view style="position: absolute;bottom: 0;width: 100%;height: 760rpx;">
<view class="kaituan1">
<view class="kaituan1-title">
差{{groupItem.groupRule.groupCount - 1}}人即可成团
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/21b403bd13414ce79ad73cf1c8e3de98.png"
alt="" style="width: 120rpx;height: 22rpx;position: absolute;bottom: 0;right: 30rpx;" />
</view>
<view class="kaituan1-title1">
快呼唤小伙伴参加吧!
</view>
</view>
<view class="kaituan2">
<view class="kaituan22">
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/ecd00dab1c9c44198d765bc08bc1bd71.png"
alt=""
style="width: 90rpx;height: 90rpx;border-radius: 90rpx;margin: 0 auto;display: block;" />
</view>
<view class="kaituan22" v-for="(n,index) in groupItem.groupRule.groupCount - 1" :key="index">
<view class="weipincheng">
+
</view>
</view>
</view>
<view class="kaituan3" style="display: flex;margin-left: auto;margin-right: auto;width: 50%;">
剩余
<uni-countdown :show-day="false" :hour="23" :minute="59" :second="59" :font-size="16" color="red" />
结束
</view>
<view class="kaituan4">
<button open-type="share" style="background:transparent;border:none;color:inherit;font-size:inherit;display:inline-flex;align-items:center;">
分享至微信 <uni-icons type="weixin" size="15"></uni-icons>
</button>
</view>
<view class="kaituan5">
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/c1f1b45c98fa4db1a1e5f98b3a0573c2.png"
alt="" style="width: 520rpx;height: 150rpx;margin: 0 auto;display: block;" />
</view>
</view>
</view>
</uni-popup>
<uni-popup ref="couponPopup" type="bottom" background-color="#F5F8F5">
<view class="coupon-popup">
<view class="coupon-popup-title">
选择优惠券
<uni-icons type="closeempty" size="24" @tap="$refs.couponPopup.close()" class="coupon-popup-close"></uni-icons>
</view>
<scroll-view scroll-y class="coupon-scroll">
<view class="coupon-card" v-for="(item, index) in availableCoupons" :key="index" @tap="selectCoupon(item)">
<view class="coupon-card-main">
<view class="coupon-card-price">
<text>¥</text>{{item.discountAmount}}
</view>
<view class="coupon-card-info">
<view class="coupon-card-name">{{item.couponName}}</view>
<view class="coupon-card-limit" v-if="item.minAmount > 0">满{{item.minAmount}}可用</view>
<view class="coupon-card-limit" v-else>无门槛使用</view>
</view>
</view>
<uni-icons v-if="selectedCoupon && selectedCoupon.id === item.id" type="checkmarkempty" size="20" color="#0b9b73"></uni-icons>
<view v-else class="coupon-card-radio"></view>
</view>
<view class="coupon-empty-state" v-if="availableCoupons.length===0">
暂无可用优惠券
</view>
<view class="coupon-scroll-bottom"></view>
</scroll-view>
<view class="coupon-popup-footer" v-if="availableCoupons.length>0">
<view class="coupon-clear-btn" @tap="selectCoupon(null)">
不使用优惠券
</view>
</view>
</view>
</uni-popup>
<delivery-time-op @timeCallback="timeCallback" :dodge="true" ref='model' :content="content" :barHidth='600'
title="选择送达时间">
> </delivery-time-op>
<view class="free-order-mask" v-if="freeOrderEffectVisible" @tap.stop="closeFreeOrderEffect">
<view class="free-order-card" @tap.stop>
<view class="free-order-rays"></view>
<view class="free-order-orb orb-1"></view>
<view class="free-order-orb orb-2"></view>
<view class="free-order-confetti confetti-1"></view>
<view class="free-order-confetti confetti-2"></view>
<view class="free-order-confetti confetti-3"></view>
<view class="free-order-confetti confetti-4"></view>
<view class="free-order-confetti confetti-5"></view>
<view class="free-order-star star-1"></view>
<view class="free-order-star star-2"></view>
<view class="free-order-star star-3"></view>
<view class="free-order-badge">今日好运爆棚</view>
<view class="free-order-title">锦鲤附体</view>
<view class="free-order-subtitle">这单居然被你免掉了</view>
<view class="free-order-amount">
<text class="amount-label" style="margin-top: 20rpx;">免单</text>
<text class="amount-number" style="margin-top: 20rpx;">{{freeOrderAmount}}</text>
<text class="amount-unit" style="margin-top: 20rpx;">元</text>
</view>
<view class="free-order-btn" @tap.stop="closeFreeOrderEffect">开心收下</view>
<view class="free-order-subtitle">未支付免单资格会传递给下一个小伙伴</view>
</view>
</view>
<common-loading />
</view>
</template>
<script>
import deliveryTimeOp from '@/components/delivery-time-op/delivery-time-op.vue'
import addressList from '@/package1/address/addressList.vue'
export default {
data() {
return {
warnPopup: 'shdz',
orderScene: '',
isPaotui: true,
menuButtonInfo: {},
formData: {
address: null,
isImmediately: true,
deliveryTime: '',
peisongyuan: ''
},
nowMake:true,
content: [],
remark:'',
selected: 'buzhiding',
customCommission: '0',
shopItem: {},
cartItems: [],
groupItem: null,
isGroupBuy: false,
isFaceToFace: false,
isPack: 0,
assignedWorker: null,
immediateTimeStr: '',
totalPackageFee: 0,
backendTotalAmount: 0,
currentOrderId: '',
createdOrderInfo: null,
isPaymentSuccessGroupInitiate: false,
availableCoupons: [],
selectedCoupon: null,
freeOrderEffectVisible: false,
freeOrderAmount: '0.00'
}
},
components: {
deliveryTimeOp,
addressList
},
filters: {
sliceMsg(val) {
var name = ''
if (typeof(val) == 'string') {
let newObj = JSON.parse(val)
for (let as in newObj) {
name = newObj[as].specPrice
}
}
return name;
}
},
onLoad(option) {
this.orderScene = option.orderScene || '';
if (option.shopItem) {
this.shopItem = JSON.parse(decodeURIComponent(option.shopItem));
}
if (option.cart) {
this.cartItems = JSON.parse(decodeURIComponent(option.cart));
this.isGroupBuy = false;
}
if (option.item) {
this.groupItem = JSON.parse(decodeURIComponent(option.item));
console.log("1111111",this.groupItem)
this.isGroupBuy = this.groupItem.orderType === 2;
this.isFaceToFace = this.groupItem.isFaceToFace || false;
this.orderScene = this.groupItem.orderScene || this.orderScene;
}
if (option.packageFee) {
this.totalPackageFee = parseFloat(option.packageFee) || 0;
}
if (this.isStoreGroupOrder) {
this.isPaotui = false;
this.nowMake = false;
this.isPack = 0;
this.totalPackageFee = 0;
}
},
computed: {
goodsAmountCalc() {
if (this.isGroupBuy && this.groupItem) {
if(this.groupItem.item.moreBuyData){
let allPrice = parseFloat(this.groupItem.groupRule.groupPrice)
for(let a = 0;a<this.groupItem.item.moreBuyData.length;a++){
allPrice += parseFloat(Number(this.sliceMsg1(this.groupItem.item.moreBuyData[a].attributeListPrice)) * this.groupItem.item.moreBuyData[a].quantity);
}
return parseFloat(allPrice);
}else{
return parseFloat(this.groupItem.groupRule.groupPrice);
}
} else {
return this.cartItems.reduce((acc, curr) => acc + (curr.quantity * parseFloat(curr.price)), 0);
}
},
isStoreGroupOrder() {
return this.orderScene === 'storeGroup' || (this.groupItem && this.groupItem.orderScene === 'storeGroup') || this.shopItem.merchantType == 2;
},
highFloorFeeCalc() {
if (this.selected === 'zhiding' && this.assignedWorker) {
let hFee = parseFloat(this.assignedWorker.highFloorFee || 0);
if (hFee > 0 && this.formData.address && parseInt(this.formData.address.floor) > 3) {
return hFee;
}
}
return 0;
},
packageFee() {
if (this.totalPackageFee > 0) return this.totalPackageFee;
let fee = 0;
if (this.isGroupBuy && this.groupItem && this.groupItem.item) {
fee = parseFloat(this.groupItem.item.lunchBox || 0);
} else if (this.cartItems && this.cartItems.length > 0) {
for (let cart of this.cartItems) {
if (cart.item) {
fee += parseFloat(cart.item.lunchBox || 0) * cart.quantity;
}
}
}
return fee;
},
deliveryFeeCalc() {
if (!this.isPaotui) return 0;
let isJoiningFaceToFace = this.isGroupBuy && this.groupItem && this.groupItem.groupId && this.groupItem
.isFaceToFace;
if (isJoiningFaceToFace)
return 0; // Front-end doesn't know exact fee, relies on backend after order creation
let commission = 0;
if (this.selected === 'zhiding') {
if (!this.assignedWorker) return 0;
commission = parseFloat(this.assignedWorker.orderBkge || 3);
} else {
if (this.customCommission !== '' && this.customCommission !== null && !isNaN(parseFloat(this
.customCommission))) {
commission = parseFloat(this.customCommission);
}
}
if (this.isGroupBuy && this.groupItem && this.groupItem.isFaceToFace && !this.groupItem.groupId) {
let members = parseInt(this.groupItem.groupRule.groupCount) || 1;
if (this.selected === 'zhiding') {
let extra = members > 2 ? (members - 2) * 0.5 : 0;
return Math.ceil(((commission + this.highFloorFeeCalc + extra) / members) * 100) / 100;
} else {
return Math.ceil(((commission + this.highFloorFeeCalc) / members) * 100) / 100;
}
}
return commission + this.highFloorFeeCalc;
},
totalAmountCalc() {
let total = this.preDiscountTotal;
if (this.selectedCoupon) {
total -= parseFloat(this.selectedCoupon.discountAmount);
}
return total > 0 ? total : 0.01;
},
preDiscountTotal() {
if(this.isPaotui==true){
return this.goodsAmountCalc + this.packageFee + this.deliveryFeeCalc;
}else{
return this.goodsAmountCalc;
}
}
},
watch: {
preDiscountTotal(newVal, oldVal) {
if (newVal !== oldVal) {
this.fetchCoupons();
}
}
},
onShow() {
this.menuButtonInfo = uni.getMenuButtonBoundingClientRect()
this.initAddress()
//this.fetchCoupons();
const now = new Date();
const startTime = new Date(now);
const endTime = new Date(now);
startTime.setMinutes(startTime.getMinutes() + 20);
endTime.setMinutes(endTime.getMinutes() + 35);
const startStr =
`${startTime.getHours().toString().padStart(2, '0')}:${startTime.getMinutes().toString().padStart(2, '0')}`;
const endStr =
`${endTime.getHours().toString().padStart(2, '0')}:${endTime.getMinutes().toString().padStart(2, '0')}`;
this.immediateTimeStr = `${startStr}-${endStr}`;
uni.$on('updateDeliveryWorker', (worker) => {
this.assignedWorker = worker;
this.selected = 'zhiding';
});
},
onShareAppMessage(res) {
if (this.isPaymentSuccessGroupInitiate) {
let groupId = this.createdOrderInfo.groupInfo.id;
let targetMembers = this.groupItem?.groupRule?.groupCount || 2;
let shopItemStr = encodeURIComponent(JSON.stringify(this.shopItem));
let isFTF = this.isFaceToFace ? 1 : 0;
console.log(shopItemStr)
let sceneQuery = this.isStoreGroupOrder ? '&orderScene=storeGroup' : '';
let path = `/package2/group/groupBuySingle?type=shop&item=${shopItemStr}&groupId=${groupId}&targetMembers=${targetMembers}&isFaceToFace=${isFTF}${sceneQuery}`;
return {
title: '我发起了一个拼团,快来一起拼单吧!',
path: path,
imageUrl:'https://jewel-shop.oss-cn-beijing.aliyuncs.com/62c9aa038b2541ad9c400a76ddae7ef8.png'
}
}
return {
title: '买饭',
path: '/pages/index/index'
}
},
onUnload() {
uni.$off('updateDeliveryWorker');
uni.removeStorageSync('pendingAssignWorker');
},
methods: {
nowMakeMethod(){
this.nowMake = !this.nowMake
},
initAddress() {
let cachedAddress = uni.getStorageSync('selectedAddress');
if (cachedAddress) {
this.formData.address = cachedAddress;
} else {
let that = this;
that.tui.request("/app/userAddress/list", "GET", {
userId: uni.getStorageSync('id')
}, false, true).then((res) => {
if (res.code == 200 && res.result && res.result.length > 0) {
// Find default address or use the first one
let target = res.result.find(item => item.isDefault == 1) || res.result[0];
that.formData.address = target;
uni.setStorageSync('selectedAddress', target);
}
}).catch(() => {});
}
},
handleSelectAddress(address) {
this.formData.address = address;
uni.setStorageSync('selectedAddress', address);
this.$refs.bookPopup.close();
},
handleSyncAddress(address) {
this.formData.address = address;
},
closeAddressBook() {
this.$refs.bookPopup.close();
},
getSpecDisplayString(specs) {
if (!specs) return '';
let arr = [];
for (let k in specs) {
arr.push(specs[k]);
}
return arr.join(',');
},
submitPay() {
let isJoiningFaceToFace = this.isGroupBuy && this.groupItem && this.groupItem.groupId && this.groupItem
.isFaceToFace;
if (this.isPaotui && !this.formData.address && !isJoiningFaceToFace) {
this.warnPopup = 'shdz';
this.$refs.warnPopup.open();
return;
}
if (this.isPaotui && this.selected === 'buzhiding' && !isJoiningFaceToFace) {
let comm = parseFloat(this.customCommission);
if (isNaN(comm) || comm <= 0) {
this.warnPopup = 'psyj';
this.$refs.warnPopup.open();
return;
}
}
if (this.isPaotui && this.selected === 'zhiding' && !this.assignedWorker && !isJoiningFaceToFace) {
this.warnPopup = 'psy';
this.$refs.warnPopup.open();
return;
}
this.submitOrderToBackend();
},
goDetail() {
let shopArea = this.shopItem.shopArea || '';
let putArea = this.formData.address ? this.formData.address.areaId : '';
if(shopArea == '' || putArea == ''){
uni.showToast({
title: '请先选择取货和收货地址',
icon: 'none'
})
return;
}
uni.navigateTo({
url: `/package1/index/deliveryPersonList?orderType=0&shopAreaId=${shopArea}&putAreaId=${putArea}`
})
},
openCouponPopup() {
this.fetchCoupons();
this.$refs.couponPopup.open('bottom');
},
fetchCoupons() {
let userId = uni.getStorageSync('id');
if (!userId) return;
let amount = this.preDiscountTotal;
this.tui.request('/mall/coupon/available', 'GET', {
userId: userId,
regionId:JSON.parse(uni.getStorageSync('area')).id,
applyScene: 1,
amount: amount,
merchantId: this.shopItem.id || this.shopItem.shopId || '0'
}, false, true).then((res) => {
if (res.code == 200 && res.result) {
this.availableCoupons = res.result;
if (this.selectedCoupon) {
let stillValid = this.availableCoupons.find(c => c.id === this.selectedCoupon.id);
if (!stillValid) this.selectedCoupon = null;
}
}
});
},
selectCoupon(item) {
this.selectedCoupon = item;
this.$refs.couponPopup.close();
},
openAddressBook() {
this.$refs.bookPopup.open('bottom')
},
checkTime(type) {
if (type === this.formData.isImmediately) {
if (type === false) {
this.$refs.model.open()
this.generateDeliveryTimes()
}
return;
}
this.formData.isImmediately = type;
if (this.formData.isImmediately === false) {
this.$refs.model.open()
this.generateDeliveryTimes()
}
},
checkVoucher(type) {
if (type == this.selected) return;
this.selected = type;
if (this.selected == 'buzhiding') {
this.formData.peisongyuan = "";
this.assignedWorker = null;
}
},
wxPayment() {
let that = this;
if (!this.currentOrderId || !this.backendTotalAmount) {
uni.showToast({
title: this.currentOrderId + this.backendTotalAmount,
icon: 'none'
})
return;
}
let amountInCents = Math.round(this.backendTotalAmount * 100);
let payDesc = '商城订单';
this.tui.request("/api/wechat/pay/unified-order", "POST", {
openid: uni.getStorageSync('miniProgramOpenid') || 'test-openid',
amount: amountInCents, // 支付金额(分)
description: payDesc,
outTradeNo: this.currentOrderId
}, false, false).then((res) => {
if (res.code == 200) {
uni.requestPayment({
provider: 'wxpay',
timeStamp: res.timeStamp,
nonceStr: res.nonceStr,
package: res.package,
signType: res.signType,
paySign: res.paySign,
success: function(res2) {
/* uni.showToast({ title: '支付成功', icon: 'success' });
that.tui.request("/api/wechat/pay/paySuccess", "POST", {
outTradeNo: that.currentOrderId
}, false, false).then((res3) => {
if(res3.code == 200){
that.handlePaymentSuccess();
}else{
that.tui.toast("订单创建失败,请联系客服处理");
}
}) */
that.handlePaymentSuccess();
},
fail: function(err) {
uni.redirectTo({
url: '/package1/order/orderDetail?id=' + that.currentOrderId
});
}
});
} else {
// 模拟支付成功(用于测试环境)
if (res.code == 404 || res.code == 500 || res.code == 400 || !res.code) {
that.tui.request(
`/hiver/order/payMallOrderSuccess?orderId=${that.currentOrderId}&workerId=${that.assignedWorker ? that.assignedWorker.workerId : ''}`,
"POST", {}, false, false).then(res2 => {
that.$refs.payPopup.close();
uni.showToast({
title: '支付成功(模拟)',
icon: 'none'
});
setTimeout(() => {
that.handlePaymentSuccess();
}, 1500);
}).catch(e => {
uni.showToast({
title: '请求失败',
icon: 'none'
})
});
} else {
uni.showToast({
title: res.message,
icon: 'none'
})
}
}
})
},
handlePaymentSuccess() {
if (!this.isGroupBuy) {
uni.redirectTo({
url: '/package1/order/orderConfirm?id=' + this.currentOrderId + '&amount=' + this.backendTotalAmount
});
} else {
let isInitiating = !this.groupItem.groupId;
let isJoining = !!this.groupItem.groupId;
if (isInitiating) {
this.isPaymentSuccessGroupInitiate = true;
this.$refs.pintuanPopup.open('center');
return;
} else if (isJoining) {
uni.redirectTo({
url: '/package1/order/orderConfirm?id=' + this.currentOrderId + '&amount=' + this.backendTotalAmount
});
}
}
},
onPintuanPopupChange(e) {
if(!e.show){
uni.redirectTo({
url: '/package1/order/orderConfirm?id=' + this.currentOrderId + '&amount=' + this.backendTotalAmount
});
}
},
getMustFinishTime() {
if (!this.formData.deliveryTime || this.formData.deliveryTime === '自动送达' || this.formData.deliveryTime ===
'尽快送达'){
const now = new Date();
now.setMinutes(now.getMinutes() + 35);
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}`;
}else{
let timeStr = this.formData.deliveryTime;
if (timeStr.length === 5) {
let [h, m] = timeStr.split(':');
let targetHour = parseInt(h);
let d = new Date();
if (targetHour < d.getHours()) d.setDate(d.getDate() + 1);
let yyyy = d.getFullYear();
let MM = String(d.getMonth() + 1).padStart(2, '0');
let DD = String(d.getDate()).padStart(2, '0');
return `${yyyy}-${MM}-${DD}T${timeStr}:00`;
}
}
return null;
},
sliceMsg1(val) {
var name = ''
if (typeof(val) == 'string') {
let newObj = JSON.parse(val)
for (let as in newObj) {
name = newObj[as].specPrice
}
}
return name;
},
submitOrderToBackend() {
let isJoiningFaceToFace = this.isGroupBuy && this.groupItem && this.groupItem.groupId && this.groupItem
.isFaceToFace;
let items = [];
if (this.isGroupBuy && this.groupItem) {
if(this.groupItem.item.moreBuyData){
for(let a = 0;a<this.groupItem.item.moreBuyData.length;a++){
items.push({
productId: this.groupItem.item.moreBuyData[a].id,
specs: '',
price: parseFloat(this.sliceMsg1(this.groupItem.item.moreBuyData[a].attributeListPrice)),
quantity: this.groupItem.item.moreBuyData[a].quantity
});
}
}
items.push({
productId: this.groupItem.item.id,
productName: this.groupItem.item.productName,
productPicture: this.groupItem.item.productPicture,
specs: JSON.stringify(this.groupItem.specs || {}),
price: parseFloat(this.groupItem.groupRule.groupPrice),
isMain:0,
quantity: 1
});
} else {
for (let cart of this.cartItems) {
items.push({
productId: cart.item.id,
specs: JSON.stringify(cart.specs || {}),
price: parseFloat(cart.price),
quantity: cart.quantity
});
}
}
let deliveryType = this.isStoreGroupOrder ? 2 : (this.isPaotui ? 1 : 2);
let payload = {
userId: uni.getStorageSync('id') || 'test-user123',
shopId: this.shopItem.id,
deliveryType: deliveryType,
isPack: this.isStoreGroupOrder ? 0 : (this.isPaotui ? 1 : this.isPack),
packageFee: this.isPaotui && !this.isStoreGroupOrder ? this.packageFee : 0,
remark: this.remark,
items: items,
receiverName: this.formData.address ? this.formData.address.receiverName : '',
receiverPhone: this.formData.address ? this.formData.address.phone : '',
receiverAddress: this.formData.address ? ((this.formData.address.areaName || '') + (this.formData
.address.floor ? this.formData.address.floor + '层' : '') + (this.formData.address
.roomNum || '')) : '',
shopName: this.shopItem.shopName,
shopPhone: this.shopItem.contactPhone || '',
shopAddress: this.shopItem.shopAddress || ''
};
let mft = this.getMustFinishTime();
if (mft) payload.mustFinishTime = mft;
if (deliveryType === 1 && !isJoiningFaceToFace) {
payload.addressId = this.formData.address ? this.formData.address.id : null;
payload.getAreaId = this.shopItem.shopArea || null;
payload.putAreaId = this.formData.address ? this.formData.address.areaId : null;
}
payload.userCouponId = this.selectedCoupon ? this.selectedCoupon.id : null;
if (this.isGroupBuy && this.groupItem) {
if (this.groupItem.groupId) {
payload.groupId = this.groupItem.groupId;
} else {
payload.groupParam = {
targetMembers: parseInt(this.groupItem.groupRule.groupCount),
isFaceToFace: this.groupItem.isFaceToFace ? 1 : 0,
selfCommission: this.selected === 'buzhiding' ? parseFloat(this.customCommission || 0) :
null
};
}
}
if (this.isPaotui && !isJoiningFaceToFace) {
if (this.selected === 'zhiding' && this.assignedWorker) {
payload.workerParam = {
workerId: this.assignedWorker.workerId,
workerPhone: this.assignedWorker.mobile,
workerName: this.assignedWorker.workerName,
orderBkge: parseFloat(this.assignedWorker.orderBkge || 0) + this.highFloorFeeCalc
};
} else if (this.selected === 'buzhiding') {
payload.workerParam = {
orderBkge: parseFloat(this.customCommission || 0)
};
}
}
uni.showLoading({
title: '创建订单中...'
});
if(this.nowMake && deliveryType == 2 && !this.isStoreGroupOrder){
payload.userRequireMake = 1
}
if(this.isStoreGroupOrder){
payload.otherOrder = 2
}
payload.regionId = JSON.parse(uni.getStorageSync('area')).id
this.tui.request("/mall/order/create", "POST", payload, false, false).then(res => {
uni.hideLoading();
if (res.success && res.result) {
let orderId = res.result.id;
let totalAmount = res.result.totalAmount;
this.backendTotalAmount = totalAmount;
this.currentOrderId = orderId;
this.createdOrderInfo = res.result;
if(res.result.isFreeOrder == 1){
this.showFreeOrderEffect(res.result);
}
this.$refs.payPopup.open('bottom');
} else {
uni.showToast({
title: res.message || '下单失败',
icon: 'none'
});
}
}).catch(err => {
uni.hideLoading();
});
},
showFreeOrderEffect(orderInfo) {
let amount = orderInfo && orderInfo.freeAmount != null ? parseFloat(orderInfo.freeAmount) : 0;
if (isNaN(amount)) amount = 0;
this.freeOrderAmount = amount.toFixed(2);
this.freeOrderEffectVisible = true;
if (uni.vibrateShort) {
uni.vibrateShort({
type: 'medium'
});
}
},
closeFreeOrderEffect() {
this.freeOrderEffectVisible = false;
},
//时间选择器获取时间数据
generateDeliveryTimes() {
const now = new Date();
const today = new Date(now);
const tomorrow = new Date(now);
tomorrow.setDate(tomorrow.getDate() + 1);
// 星期几
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
const todayWeekday = weekdays[today.getDay()];
const todayStr = `今天 (${todayWeekday})`;
// 明天的日期格式:月-日(不补零)
const month = tomorrow.getMonth() + 1;
const day = tomorrow.getDate();
const tomorrowStr = `${month}-${day}`;
// ----- 生成今天的时间列表 -----
const todayTimelist = [{
timestr: '自动送达'
}];
const currentHour = now.getHours();
const currentMinute = now.getMinutes();
// 计算下一个半小时点
let nextHour = currentHour;
let nextMinute = 30;
if (currentMinute >= 30) {
nextHour = currentHour + 1;
nextMinute = 0;
}
// 从下一个半小时点开始,直到 23:30
for (let h = nextHour; h <= 23; h++) {
const startMin = (h === nextHour) ? nextMinute : 0;
for (let m = startMin; m < 60; m += 30) {
if (h === 23 && m > 30) continue; // 不超过 23:30
const timeStr = `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}`;
todayTimelist.push({
timestr: timeStr
});
}
}
// ----- 生成明天的时间列表(全天 00:00 ~ 23:30)-----
const tomorrowTimelist = [];
for (let h = 0; h <= 23; h++) {
for (let m = 0; m < 60; m += 30) {
if (h === 23 && m > 30) continue;
const timeStr = `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}`;
tomorrowTimelist.push({
timestr: timeStr
});
}
}
this.content = [{
timezh: todayStr,
timelist: todayTimelist
},
{
timezh: tomorrowStr,
timelist: tomorrowTimelist
}
];
},
//时间选择器点击后
timeCallback(val) {
this.formData.deliveryTime = val.timestr
this.$refs.model.close()
},
back() {
uni.navigateBack()
}
}
}
</script>
<style lang="scss">
$primary: #00231C;
$muted: #6f7f79;
$brand-start: #e3ff96;
$brand-end: #a6ffea;
$card-shadow: 0 16rpx 44rpx rgba(8, 36, 29, 0.08);
page {
width: 100%;
height: 100%;
font-size: 24rpx;
background: #F5F8F5;
color: $primary;
}
.page1 {
width: 100%;
min-height: 100%;
font-size: 24rpx;
position: relative;
overflow-x: hidden;
background:
linear-gradient(180deg, rgba(245, 248, 245, 0) 0, #F5F8F5 360rpx),
#F5F8F5;
}
.title {
background: url('https://jewel-shop.oss-cn-beijing.aliyuncs.com/8bc15960c2dc40268e295d6dd23aecce.png') no-repeat;
width: 100%;
height: 340rpx;
background-size: 100% 100%;
}
.title-sreach {
width: 100%;
display: flex;
height: 200rpx;
position: relative;
}
.back-btn {
position: absolute;
bottom: 0;
left: 14rpx;
width: 68rpx;
height: 68rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: rgba(255, 255, 255, 0.34);
backdrop-filter: blur(8rpx);
}
.title-name {
padding-top: 110rpx;
font-size: 36rpx;
font-weight: 700;
flex: 1;
text-align: center;
}
.tab-wrap {
position: absolute;
top: 184rpx;
left: 0;
width: 100%;
z-index: 2;
}
.tab1 {
width: 100%;
height: 160rpx;
position: relative;
img {
width: 100%;
height: 100%;
background-size: 100%;
}
}
.tab-bg {
position: absolute;
left: 0;
top: 0;
}
.tab-hit-area {
width: 100%;
height: 160rpx;
position: absolute;
top: 0;
left: 0;
display: flex;
}
.tab-hit-item {
width: 50%;
height: 160rpx;
}
.box1 {
width: calc(100% - 40rpx);
box-sizing: border-box;
margin: 20rpx auto 24rpx;
background: #fff;
border-radius: 30rpx;
padding: 26rpx;
box-shadow: $card-shadow;
}
.goods-img {
width: 150rpx;
height: 150rpx;
position: relative;
flex-shrink: 0;
img {
width: 100%;
background-size: 100%;
height: 100%;
border-radius: 24rpx;
box-shadow: 0 12rpx 24rpx rgba(0, 35, 28, 0.08);
}
}
.goods-content {
flex: 1;
padding-left: 20rpx;
}
.goods-name {
font-size: 30rpx;
font-weight: 800;
line-height: 42rpx;
color: $primary;
}
.goods-content-center {
display: flex;
margin: 12rpx 0;
color: $muted;
font-size: 24rpx;
}
.pintuan-left-price {
text-align: right;
font-weight: 800;
color: $primary;
display: flex;
align-items: center;
justify-content: flex-end;
}
.goods-content-bottom {
display: flex;
line-height: 52rpx;
color: $muted;
align-items: center;
}
.address-box {
background: #fff;
min-height: 92rpx;
line-height: 1.4;
font-size: 30rpx;
font-weight: 800;
padding: 0 30rpx;
margin: 18rpx 20rpx 0;
border-radius: 28rpx;
box-shadow: $card-shadow;
display: flex;
align-items: center;
}
.time-box {
display: flex;
padding: 20rpx;
}
.time1 {
min-height: 96rpx;
flex: 1;
border-radius: 24rpx;
text-align: center;
line-height: 40rpx;
padding: 16rpx 10rpx;
background: rgba(255, 255, 255, 0.86);
border: 2rpx solid rgba(255, 255, 255, 0.9);
box-shadow: 0 10rpx 28rpx rgba(0, 35, 28, 0.05);
box-sizing: border-box;
transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.time1 + .time1 {
margin-left: 20rpx;
}
.time1:active,
.address-box:active,
.coupon-row:active,
.bottom-btn:active {
transform: scale(0.98);
}
.time1-active {
background: linear-gradient(110deg, $brand-start, $brand-end);
border-color: rgba(255, 255, 255, 0.72);
box-shadow: 0 14rpx 32rpx rgba(49, 224, 183, 0.2);
}
.time-title {
font-size: 28rpx;
font-weight: 800;
color: $primary;
}
.time-desc {
margin-top: 4rpx;
font-size: 21rpx;
color: $muted;
}
.radio-check {
background: linear-gradient(90deg, $brand-start, $brand-end);
width: 42rpx;
height: 42rpx;
border-radius: 42rpx;
text-align: center;
line-height: 42rpx;
margin: 0 18rpx 0 0;
box-shadow: 0 6rpx 16rpx rgba(49, 224, 183, 0.22);
}
.radio-no-check {
width: 42rpx;
height: 42rpx;
border-radius: 42rpx;
border: 2rpx solid #e8eeee;
margin: 0 18rpx 0 0;
background: #fff;
text-align: center;
line-height: 42rpx;
}
.buy-bottom {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
min-height: 146rpx;
display: flex;
padding-bottom: 20rpx;
background: rgba(255, 255, 255, 0.92);
z-index: 99;
box-shadow: 0 -10rpx 34rpx rgba(0, 35, 28, 0.12);
backdrop-filter: blur(14rpx);
}
.bottom-btn {
display: flex;
align-items: center;
justify-content: center;
width: 90%;
height: 92rpx;
background: linear-gradient(100deg, $brand-start 0%, $brand-end 100%);
font-size: 28rpx;
font-weight: 800;
line-height: 92rpx;
text-align: center;
border-radius: 100rpx;
margin: 22rpx auto 24rpx;
box-shadow: 0 16rpx 30rpx rgba(49, 224, 183, 0.22);
transition: transform 0.18s ease;
}
.pay-btn-gif {
width: 42rpx;
height: 42rpx;
margin-right: 8rpx;
flex-shrink: 0;
}
.ziqu-text{
align-items: center;
display: flex;
color: $primary;
line-height: 38rpx;
}
.btn {
width: 95%;
height: 100rpx;
font-size: 32rpx;
font-weight: 700;
background: linear-gradient(90deg, $brand-start, $brand-end);
border-radius: 100rpx;
line-height: 100rpx;
text-align: center;
margin: 40rpx auto 0;
}
.ziqu-box {
background: rgba(255, 255, 255, 0.9);
width: calc(100% - 40rpx);
margin: 12rpx auto 22rpx;
border-radius: 28rpx;
position: relative;
overflow: hidden;
box-shadow: $card-shadow;
}
.ziqu-xuanfu {
position: absolute;
top: 0;
right: 0;
padding: 10rpx 22rpx;
background: linear-gradient(90deg, $brand-start, $brand-end);
border-top-right-radius: 28rpx;
border-bottom-left-radius: 24rpx;
font-weight: 700;
font-size: 20rpx;
}
.ziqu-address {
display: flex;
min-height: 116rpx;
background: #fff;
width: 90%;
border-radius: 24rpx;
font-size: 26rpx;
margin: 64rpx auto 24rpx;
font-weight: bold;
line-height: 40rpx;
box-shadow: 0 10rpx 24rpx rgba(0, 35, 28, 0.05);
img {
width: 40rpx;
height: 40rpx;
margin: 36rpx 20rpx 0 30rpx;
}
}
.address-empty,
.address-content {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.address-main {
flex: 1;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.address-change {
color: #0b9b73;
font-size: 25rpx;
font-weight: 600;
margin-left: 20rpx;
display: flex;
align-items: center;
}
.delivery-card {
width: calc(100% - 40rpx);
margin: 0 auto 24rpx;
background: #fff;
border-radius: 30rpx;
box-shadow: $card-shadow;
overflow: hidden;
}
.delivery-head {
padding: 24rpx 30rpx 18rpx;
background: linear-gradient(180deg, rgba(166, 255, 234, 0.18), rgba(255, 255, 255, 0));
line-height: 38rpx;
}
.delivery-title {
font-size: 30rpx;
font-weight: 800;
margin-bottom: 8rpx;
}
.delivery-desc {
font-size: 23rpx;
color: $muted;
line-height: 36rpx;
}
.delivery-options {
padding: 10rpx 30rpx 30rpx;
}
.delivery-option {
display: flex;
align-items: center;
min-height: 72rpx;
font-size: 28rpx;
font-weight: 800;
line-height: 50rpx;
}
.delivery-option + .delivery-option {
margin-top: 12rpx;
padding-top: 18rpx;
border-top: 1rpx solid #f0f3f2;
}
.delivery-choice {
width: 50%;
display: flex;
align-items: center;
}
.commission-input {
width: 50%;
display: flex;
justify-content: flex-end;
align-items: center;
color: $muted;
font-weight: normal;
font-size: 24rpx;
text {
margin-right: 10rpx;
}
input {
width: 132rpx;
height: 52rpx;
min-height: 52rpx;
text-align: center;
font-size: 28rpx;
font-weight: normal;
border-radius: 16rpx;
background: #f6faf8;
border: 1rpx solid #e5efeb;
}
}
.worker-entry {
width: 50%;
color: $muted;
text-align: right;
font-size: 25rpx;
font-weight: 600;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.floor-fee-tip {
margin-top: 20rpx;
color: #ff5722;
font-size: 24rpx;
background: #fff5f1;
padding: 14rpx 20rpx;
border-radius: 16rpx;
}
.shop-title {
width: 100%;
line-height: 62rpx;
font-size: 29rpx;
font-weight: 800;
color: $primary;
}
.goods-card {
display: flex;
padding: 18rpx;
background: linear-gradient(180deg, rgba(247, 250, 248, 0.9), rgba(247, 248, 248, 0.62));
border-radius: 24rpx;
margin-bottom: 20rpx;
border: 1rpx solid rgba(232, 239, 235, 0.8);
}
.goods-count {
width: 45%;
flex: 1;
}
.group-price-tag {
background: rgba(255, 57, 57, 0.12);
padding: 4rpx 14rpx;
border-radius: 999rpx;
margin-left: 20rpx;
font-size: 23rpx;
}
.fee-list {
margin-top: 10rpx;
border-top: 1rpx solid #f0f3f2;
}
.fee-row,
.coupon-row,
.total-row {
min-height: 80rpx;
display: flex;
align-items: center;
}
.fee-row + .fee-row {
border-top: 1rpx solid #f5f6f6;
}
.fee-label {
flex: 1;
color: $muted;
font-weight: 700;
}
.fee-tip {
font-size: 20rpx;
color: #9aa6a2;
font-weight: normal;
}
.fee-value {
color: $primary;
font-weight: 800;
}
.pack-options {
display: flex;
align-items: center;
justify-content: flex-end;
}
.pack-option {
display: flex;
align-items: center;
color: $primary;
font-weight: 800;
margin-left: 30rpx;
}
.remark-box {
flex: 1;
input {
width: 100%;
box-sizing: border-box;
text-align: right;
font-size: 26rpx;
font-weight: normal;
min-height: 56rpx;
height: 56rpx;
padding: 0 18rpx;
border-radius: 18rpx;
background: #f6faf8;
}
}
.coupon-row {
border-top: 1rpx solid #f0f3f2;
font-size: 28rpx;
font-weight: 700;
transition: transform 0.18s ease;
}
.coupon-label {
flex: 1;
color: $muted;
font-size: 30rpx;
}
.coupon-discount {
color: #ff5722;
}
.coupon-available {
color: #0b9b73;
}
.coupon-empty {
color: #999;
}
.total-row {
border-top: 1rpx solid #f0f3f2;
font-size: 32rpx;
font-weight: 800;
}
.total-label {
flex: 1;
}
.total-price {
color: #ff5722;
font-size: 34rpx;
}
.bottom-placeholder {
height: 166rpx;
}
.coupon-popup {
width: 100%;
height: 800rpx;
display: flex;
flex-direction: column;
border-top-left-radius: 34rpx;
border-top-right-radius: 34rpx;
overflow: hidden;
background: #F5F8F5;
}
.coupon-popup-title {
height: 104rpx;
line-height: 104rpx;
text-align: center;
font-size: 32rpx;
font-weight: 800;
border-bottom: 1rpx solid #eef2f0;
position: relative;
background: #fff;
}
.coupon-popup-close {
position: absolute;
right: 30rpx;
top: 0;
}
.coupon-scroll {
flex: 1;
padding: 22rpx;
box-sizing: border-box;
}
.coupon-card {
background: #fff;
border-radius: 24rpx;
padding: 28rpx 22rpx;
margin-bottom: 20rpx;
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: 0 12rpx 28rpx rgba(0, 35, 28, 0.06);
}
.coupon-card:active,
.coupon-clear-btn:active {
transform: scale(0.98);
}
.coupon-card-main {
display: flex;
align-items: center;
flex: 1;
}
.coupon-card-price {
color: #ff5722;
font-size: 42rpx;
font-weight: 800;
width: 140rpx;
text {
font-size: 24rpx;
}
}
.coupon-card-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
margin-left: 20rpx;
}
.coupon-card-name {
font-size: 28rpx;
font-weight: 800;
color: #333;
margin-bottom: 8rpx;
}
.coupon-card-limit {
font-size: 22rpx;
color: #999;
}
.coupon-card-radio {
width: 40rpx;
height: 40rpx;
border-radius: 50%;
border: 2rpx solid #dfe7e3;
}
.coupon-empty-state {
text-align: center;
padding-top: 100rpx;
color: #999;
}
.coupon-scroll-bottom {
height: 40rpx;
}
.coupon-popup-footer {
padding: 20rpx 40rpx calc(20rpx + env(safe-area-inset-bottom));
background: #fff;
box-shadow: 0 -8rpx 24rpx rgba(0, 35, 28, 0.06);
}
.coupon-clear-btn {
width: 100%;
height: 82rpx;
background: linear-gradient(90deg, $brand-start, $brand-end);
font-size: 30rpx;
font-weight: 800;
line-height: 82rpx;
text-align: center;
border-radius: 100rpx;
box-shadow: 0 12rpx 24rpx rgba(49, 224, 183, 0.18);
}
.ziqu-time-box {
width: 90%;
margin: 20rpx auto;
display: flex;
font-weight: 700;
}
.ziqu-call-box {
width: 90%;
display: flex;
height: 70rpx;
line-height: 70rpx;
margin: 0 auto 20rpx;
}
.ziqu-call {
flex: 1;
}
.book-popup-content {
position: relative;
height: 1200rpx;
width: 100%;
padding: 20rpx;
overflow: scroll;
}
.vue-ref {
border-radius: 20rpx !important;
}
.pintuan-popup {
background: url('https://jewel-shop.oss-cn-beijing.aliyuncs.com/780a024aefb7431ba21cf16efc8a482e.png') no-repeat;
background-size: 100%;
width: 600rpx;
height: 960rpx;
position: relative;
}
.kaituan1 {
height: 120rpx;
font-size: 44rpx;
font-weight: 700;
margin-top: 20rpx;
}
.kaituan1-title {
position: relative;
text-align: center;
img {
width: 120rpx;
height: 22rpx;
position: absolute;
bottom: 0;
right: 250rpx;
}
}
.kaituan1-title1 {
font-size: 30rpx;
height: 60rpx;
line-height: 60rpx;
text-align: center;
}
.kaituan2 {
display: flex;
width: 90%;
margin: 40rpx auto;
}
.kaituan22 {
flex: 1;
}
.kaituan3 {
height: 80rpx;
line-height: 80rpx;
text-align: center;
color: #777;
}
.kaituan4 {
width: 85%;
height: 100rpx;
background: linear-gradient(90deg, rgba(227, 255, 150, 1), rgba(166, 255, 234, 1));
border-radius: 100rpx;
text-align: center;
line-height: 100rpx;
font-size: 30rpx;
font-weight: 700;
margin: 20rpx auto;
}
.kaituan5 {
margin: 40rpx 0 40rpx;
}
.weipincheng {
width: 90rpx;
height: 90rpx;
background: rgba(166, 255, 234, 0.24);
border-radius: 90rpx;
text-align: center;
font-size: 60rpx;
font-weight: 700;
margin-left: -6rpx;
z-index: 97;
color: #02fbdd;
border: 1px solid #a6ffea;
line-height: 80rpx;
margin: 0 auto;
}
button::after{
border: 0;
}
.free-order-mask {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
background:
radial-gradient(circle at 20% 18%, rgba(255, 139, 197, 0.34), rgba(255, 139, 197, 0) 280rpx),
radial-gradient(circle at 78% 22%, rgba(166, 255, 234, 0.4), rgba(166, 255, 234, 0) 300rpx),
radial-gradient(circle at 50% 70%, rgba(255, 243, 178, 0.28), rgba(255, 243, 178, 0) 360rpx),
linear-gradient(180deg, rgba(8, 20, 28, 0.62), rgba(18, 22, 34, 0.82));
backdrop-filter: blur(10rpx);
-webkit-backdrop-filter: blur(10rpx);
animation: freeMaskFade 0.22s ease both;
}
.free-order-card {
position: relative;
width: 630rpx;
min-height: 700rpx;
padding: 54rpx 42rpx 46rpx;
box-sizing: border-box;
overflow: hidden;
text-align: center;
border-radius: 56rpx;
background:
linear-gradient(145deg, rgba(255, 255, 255, 0.74), rgba(255, 255, 255, 0.34)),
radial-gradient(circle at 16% 10%, rgba(255, 243, 178, 0.56), rgba(255, 243, 178, 0) 190rpx),
radial-gradient(circle at 88% 12%, rgba(255, 139, 197, 0.34), rgba(255, 139, 197, 0) 220rpx),
radial-gradient(circle at 50% 100%, rgba(166, 255, 234, 0.48), rgba(166, 255, 234, 0) 320rpx);
border: 2rpx solid rgba(255, 255, 255, 0.72);
box-shadow: 0 38rpx 110rpx rgba(10, 19, 35, 0.34), inset 0 0 46rpx rgba(255, 255, 255, 0.28);
backdrop-filter: blur(24rpx) saturate(1.28);
-webkit-backdrop-filter: blur(24rpx) saturate(1.28);
animation: freeCardPop 0.56s cubic-bezier(0.18, 1.35, 0.28, 1) both;
}
.free-order-rays {
position: absolute;
left: 50%;
top: -210rpx;
width: 680rpx;
height: 680rpx;
margin-left: -340rpx;
border-radius: 50%;
background:
conic-gradient(from 20deg, rgba(255, 255, 255, 0), rgba(255, 243, 178, 0.36), rgba(166, 255, 234, 0), rgba(255, 139, 197, 0.3), rgba(255, 122, 73, 0.26), rgba(255, 255, 255, 0));
opacity: 0.72;
filter: blur(1rpx);
animation: freeRaysSpin 9s linear infinite;
}
.free-order-orb {
position: absolute;
z-index: 1;
border-radius: 50%;
filter: blur(1rpx);
animation: orbFloat 4.6s ease-in-out infinite;
}
.orb-1 {
width: 150rpx;
height: 150rpx;
left: -44rpx;
top: 180rpx;
background: rgba(166, 255, 234, 0.42);
}
.orb-2 {
width: 118rpx;
height: 118rpx;
right: -26rpx;
bottom: 190rpx;
background: rgba(255, 139, 197, 0.36);
animation-delay: 0.8s;
}
.free-order-badge,
.free-order-title,
.free-order-subtitle,
.free-order-amount,
.free-order-note,
.free-order-btn {
position: relative;
z-index: 3;
}
.free-order-badge {
display: inline-flex;
align-items: center;
justify-content: center;
height: 54rpx;
padding: 0 30rpx;
border-radius: 999rpx;
color: #143a36;
font-size: 23rpx;
font-weight: 900;
letter-spacing: 1rpx;
background: linear-gradient(100deg, rgba(166, 255, 234, 0.86), rgba(255, 243, 178, 0.9), rgba(255, 183, 218, 0.78));
box-shadow: 0 12rpx 30rpx rgba(116, 242, 210, 0.22), inset 0 0 18rpx rgba(255, 255, 255, 0.42);
}
.free-order-title {
margin-top: 40rpx;
color: #252232;
font-size: 76rpx;
font-weight: 900;
letter-spacing: 5rpx;
text-shadow: 0 10rpx 28rpx rgba(255, 132, 189, 0.26);
animation: freeTitlePop 1.35s ease-in-out infinite;
}
.free-order-subtitle {
margin-top: 12rpx;
color: rgba(37, 34, 50, 0.72);
font-size: 28rpx;
font-weight: 800;
}
.free-order-amount {
display: flex;
align-items: baseline;
justify-content: center;
width: 500rpx;
text-align: center;
height: 170rpx;
margin: 50rpx auto 0;
padding: 0 30rpx;
box-sizing: border-box;
border-radius: 46rpx;
color: #fff;
font-weight: 900;
background: linear-gradient(110deg, #ff7a49 0%, #fff0a8 22%, #c8ff5d 45%, #72f7df 68%, #ff8bc5 100%);
background-size: 260% 100%;
box-shadow: 0 24rpx 58rpx rgba(255, 132, 80, 0.28), 0 0 54rpx rgba(166, 255, 234, 0.24);
border: 2rpx solid rgba(255, 255, 255, 0.72);
animation: freeAmountAura 2.8s linear infinite, freeAmountBeat 1.35s ease-in-out infinite;
}
.amount-label {
margin-right: 28rpx;
font-size: 34rpx;
letter-spacing: 2rpx;
text-shadow: 0 8rpx 18rpx rgba(0, 0, 0, 0.14);
}
.amount-number {
font-size: 76rpx;
letter-spacing: 1rpx;
text-shadow: 0 10rpx 22rpx rgba(0, 0, 0, 0.18);
}
.amount-unit {
margin-left: 14rpx;
font-size: 30rpx;
}
.free-order-note {
margin-top: 30rpx;
color: #54706a;
font-size: 25rpx;
font-weight: 800;
line-height: 38rpx;
}
.free-order-btn {
width: 380rpx;
height: 96rpx;
margin: 54rpx auto 0;
line-height: 96rpx;
border-radius: 999rpx;
color: #1e2430;
font-size: 32rpx;
font-weight: 900;
letter-spacing: 2rpx;
background: linear-gradient(100deg, #fff1a8 0%, #c9ff64 35%, #85ffe8 72%, #ffc1dd 100%);
box-shadow: 0 18rpx 42rpx rgba(125, 255, 228, 0.28), inset 0 0 22rpx rgba(255, 255, 255, 0.42);
border: 2rpx solid rgba(255, 255, 255, 0.7);
animation: rewardBtnFloat 1.8s ease-in-out infinite;
}
.free-order-confetti {
position: absolute;
z-index: 1;
width: 16rpx;
height: 34rpx;
border-radius: 8rpx;
opacity: 0.86;
animation: confettiFloat 4.2s ease-in-out infinite;
}
.confetti-1 {
left: 78rpx;
top: 128rpx;
background: #ff8bc5;
}
.confetti-2 {
left: 172rpx;
top: 78rpx;
background: #85ffe8;
animation-delay: 0.4s;
}
.confetti-3 {
right: 96rpx;
top: 154rpx;
background: #fff1a8;
animation-delay: 0.8s;
}
.confetti-4 {
right: 178rpx;
top: 82rpx;
background: #ff8a5c;
animation-delay: 1.1s;
}
.confetti-5 {
left: 300rpx;
top: 116rpx;
background: #c9ff64;
animation-delay: 1.4s;
}
.free-order-star {
position: absolute;
z-index: 2;
width: 16rpx;
height: 16rpx;
border-radius: 50%;
background: #fffdf0;
box-shadow: 0 0 26rpx rgba(255, 246, 179, 0.92);
animation: starTwinkle 1.8s ease-in-out infinite;
}
.star-1 {
left: 120rpx;
top: 264rpx;
}
.star-2 {
right: 118rpx;
top: 236rpx;
animation-delay: 0.44s;
}
.star-3 {
left: 442rpx;
bottom: 190rpx;
animation-delay: 0.82s;
}
@keyframes freeMaskFade {
0% { opacity: 0; }
100% { opacity: 1; }
}
@keyframes freeCardPop {
0% {
opacity: 0;
transform: translateY(54rpx) scale(0.78);
}
64% {
transform: translateY(-10rpx) scale(1.06);
}
100% {
opacity: 1;
transform: translateY(0) scale(1);
}
}
@keyframes freeRaysSpin {
0% { transform: rotate(0deg) scale(1); }
100% { transform: rotate(360deg) scale(1.06); }
}
@keyframes freeTitlePop {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.025); }
}
@keyframes freeAmountBeat {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.045); }
}
@keyframes freeAmountAura {
0% { background-position: 0% 50%; }
100% { background-position: 260% 50%; }
}
@keyframes rewardBtnFloat {
0%, 100% { transform: translateY(0) scale(1); }
50% { transform: translateY(-8rpx) scale(1.025); }
}
@keyframes orbFloat {
0%, 100% { transform: translateY(0) scale(1); opacity: 0.72; }
50% { transform: translateY(-24rpx) scale(1.08); opacity: 1; }
}
@keyframes confettiFloat {
0%, 100% { transform: translateY(0) rotate(0deg); opacity: 0.4; }
50% { transform: translateY(44rpx) rotate(150deg); opacity: 1; }
}
@keyframes starTwinkle {
0%, 100% { transform: scale(0.6); opacity: 0.35; }
50% { transform: scale(1.45); opacity: 1; }
}
.store-group-checkout {
background:
radial-gradient(circle at 84% 110rpx, rgba(255, 229, 190, 0.74), transparent 270rpx),
linear-gradient(180deg, #fff0df 0%, #fff8f0 420rpx, #fffaf6 100%);
color: #3f2618;
}
.store-group-checkout .title {
background:
radial-gradient(circle at 78% 22%, rgba(255, 246, 221, 0.72), transparent 240rpx),
linear-gradient(135deg, #ff8a5c 0%, #ffbd70 58%, #ffe2bf 100%);
position: relative;
overflow: hidden;
}
.store-group-checkout .box1,
.store-group-checkout .ziqu-box,
.store-group-checkout .goods-card,
.store-group-checkout .coupon-row {
border-color: rgba(255, 218, 183, 0.82);
box-shadow: 0 16rpx 38rpx rgba(178, 102, 48, 0.12);
}
.store-group-checkout .ziqu-xuanfu,
.store-group-checkout .bottom-btn,
.store-group-checkout .btn,
.store-group-checkout .coupon-clear-btn {
background: linear-gradient(90deg, #ff7444, #ffb35e);
color: #fff;
box-shadow: 0 16rpx 30rpx rgba(255, 126, 39, 0.22);
}
.store-group-checkout .shop-title,
.store-group-checkout .goods-name,
.store-group-checkout .total-label {
color: #3f2618;
}
.store-group-checkout .fee-label,
.store-group-checkout .goods-content-center,
.store-group-checkout .goods-content-bottom,
.store-group-checkout .ziqu-text {
color: #8f684c;
}
.store-group-checkout .total-price,
.store-group-checkout .coupon-discount,
.store-group-checkout .pintuan-left-price {
color: #f0441f;
}
.store-hero-effect {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: hidden;
pointer-events: none;
}
.store-orb {
position: absolute;
border-radius: 50%;
filter: blur(1rpx);
animation: storeOrbFloat 4.2s ease-in-out infinite;
}
.orb-a {
width: 260rpx;
height: 260rpx;
right: -78rpx;
top: 78rpx;
background: rgba(255, 247, 218, 0.5);
}
.orb-b {
width: 160rpx;
height: 160rpx;
left: 64rpx;
bottom: 24rpx;
background: rgba(255, 118, 73, 0.18);
animation-delay: 0.8s;
}
.store-hero-copy {
position: absolute;
left: 92rpx;
top: 132rpx;
color: #fff;
text-shadow: 0 8rpx 18rpx rgba(170, 77, 24, 0.22);
}
.store-hero-badge {
display: inline-block;
height: 42rpx;
line-height: 42rpx;
padding: 0 18rpx;
border-radius: 999rpx;
background: rgba(255, 255, 255, 0.42);
color: #9b4d28;
font-size: 21rpx;
font-weight: 900;
box-shadow: 0 10rpx 24rpx rgba(170, 77, 24, 0.1);
}
.store-hero-title {
margin-top: 14rpx;
font-size: 46rpx;
font-weight: 900;
line-height: 56rpx;
letter-spacing: 2rpx;
}
.store-hero-sub {
margin-top: 6rpx;
color: rgba(111, 61, 35, 0.78);
font-size: 24rpx;
font-weight: 800;
line-height: 34rpx;
text-shadow: none;
}
.store-verify-card {
position: absolute;
right: 30rpx;
bottom: 34rpx;
display: flex;
align-items: center;
width: 210rpx;
padding: 16rpx 18rpx;
border-radius: 30rpx;
background: rgba(255, 255, 255, 0.52);
border: 1rpx solid rgba(255, 255, 255, 0.68);
box-shadow: 0 18rpx 36rpx rgba(170, 77, 24, 0.12);
backdrop-filter: blur(10rpx);
animation: storeCardFloat 3.2s ease-in-out infinite;
}
.verify-icon {
width: 58rpx;
height: 58rpx;
margin-right: 12rpx;
border-radius: 22rpx;
background: linear-gradient(135deg, #ff7444, #ffb35e);
color: #fff;
font-size: 28rpx;
font-weight: 900;
line-height: 58rpx;
text-align: center;
}
.verify-title {
color: #3f2618;
font-size: 24rpx;
font-weight: 900;
line-height: 30rpx;
}
.verify-sub {
margin-top: 4rpx;
color: #9b6a4c;
font-size: 20rpx;
font-weight: 800;
}
.store-float-tag {
position: absolute;
padding: 8rpx 16rpx;
border-radius: 999rpx;
background: rgba(255, 255, 255, 0.54);
color: #e96632;
font-size: 20rpx;
font-weight: 900;
box-shadow: 0 10rpx 22rpx rgba(170, 77, 24, 0.1);
animation: storeTagFloat 3.6s ease-in-out infinite;
}
.tag-a {
right: 196rpx;
top: 86rpx;
transform: rotate(6deg);
}
.tag-b {
left: 330rpx;
bottom: 92rpx;
transform: rotate(-5deg);
animation-delay: 0.7s;
}
@keyframes storeOrbFloat {
0%, 100% {
transform: translateY(0) scale(1);
}
50% {
transform: translateY(-18rpx) scale(1.06);
}
}
@keyframes storeCardFloat {
0%, 100% {
transform: translateY(0) rotate(0deg);
}
50% {
transform: translateY(-10rpx) rotate(1deg);
}
}
@keyframes storeTagFloat {
0%, 100% {
transform: translateY(0) rotate(-4deg);
}
50% {
transform: translateY(-10rpx) rotate(4deg);
}
}
</style>