<template>
|
<view class="luggage-page">
|
<view class="nav-bar" :style="{ paddingTop: statusbarHeight + 'px' }">
|
<view class="nav-content" :style="{ height: navHeight + 'px' }">
|
<view class="nav-left" @click="goBack">
|
<u-icon name="arrow-left" :size="26" color="#333333"></u-icon>
|
</view>
|
<text class="nav-title">行李寄存</text>
|
<view class="nav-right"></view>
|
</view>
|
</view>
|
<!-- <view class="top-placeholder" :style="{ height: statusbarHeight + navHeight + 'px' }"></view> -->
|
<view class="top-gradient-bg"></view>
|
<view class="mode-tabs">
|
<view
|
v-for="item in modeTabs"
|
:key="item.value"
|
class="mode-tab"
|
:class="{ active: activeMode === item.value }"
|
@click="switchMode(item.value)"
|
>
|
<text>{{ item.label }}</text>
|
<view v-if="activeMode === item.value" class="mode-line"></view>
|
</view>
|
</view>
|
|
<scroll-view scroll-y class="page-scroll">
|
<view class="page-content">
|
<view v-if="activeMode === 'local'" class="service-point-card cell-card" @click="openStorePopup0">
|
<view class="cell-left with-icon">
|
<image class="cell-icon" src="/static/icon/ic_store@2x.png" mode="widthFix"></image>
|
<view class="store-cell-copy">
|
<text class="cell-title">{{ selectedStore ? selectedStore.name : servicePointPlaceholder }}</text>
|
<view class="store-cell-copy-addr1" v-if="selectedStore">
|
<image src="/static/icon/home_ic_location3@2x.png" mode="widthFix"></image>
|
<text class="store-cell-subtitle">{{ selectedStore.address }}</text>
|
</view>
|
</view>
|
</view>
|
<view class="cell-right">
|
<u-icon name="arrow-right" size="18" color="#222222"></u-icon>
|
</view>
|
</view>
|
|
<view v-else class="address-card section-card">
|
<view class="address-row" @click="openStorePopup">
|
<view class="address-left">
|
<view class="address-badge send">寄</view>
|
<view class="address-copy">
|
<text class="address-title" v-if="!sendStore">寄件地址</text>
|
<text class="address-desc" v-if="!sendStore">请选择寄件服务点</text>
|
<view v-if="sendStore" class="store-cell-copy-addr">
|
<text class="store-cell-title">{{ sendStore.name }}</text>
|
<view class="store-cell-subtitle-container">
|
<image src="/static/icon/home_ic_location3@2x.png" mode="widthFix"></image>
|
<text class="store-cell-subtitle">{{ sendStore.address }}</text>
|
</view>
|
</view>
|
</view>
|
</view>
|
<u-icon name="arrow-right" size="20" color="#222222"></u-icon>
|
</view>
|
<view class="address-row no-border" @click="openReceiveAddress">
|
<view class="address-left">
|
<view class="address-badge receive">收</view>
|
<view class="address-copy">
|
<text class="address-title" v-if="!receiveStore && !receiveAddr">取件地址</text>
|
<text class="address-desc" v-if="!receiveStore && !receiveAddr">请选择取件服务点或者其他地址</text>
|
<view v-if="receiveStore" class="store-cell-copy-addr">
|
<text class="store-cell-title">{{ receiveStore.name }}</text>
|
<view class="store-cell-subtitle-container">
|
<image src="/static/icon/home_ic_location3@2x.png" mode="widthFix"></image>
|
<text class="store-cell-subtitle">{{ receiveStore.address }}</text>
|
</view>
|
</view>
|
<view v-if="receiveAddr" class="store-cell-copy-addr">
|
<text class="store-cell-title">{{ receiveAddr.addr }}</text>
|
</view>
|
</view>
|
</view>
|
<u-icon name="arrow-right" size="20" color="#222222"></u-icon>
|
</view>
|
</view>
|
|
<view class="section-card info-card">
|
<view class="section-head">
|
<text class="section-title">收件信息</text>
|
<text class="section-desc">(必填,可委托他人代取)</text>
|
</view>
|
<view class="form-row">
|
<text class="form-label">收件人</text>
|
<input v-model="form.receiver" class="form-input" :class="{ 'filled-input': form.receiver }" type="text" placeholder="请输入收件人姓名" placeholder-style="color: #B2B2B2;" />
|
</view>
|
<view class="form-row no-border">
|
<text class="form-label">收件电话</text>
|
<input v-model="form.mobile" class="form-input" :class="{ 'filled-input': form.mobile }" type="number" placeholder="请输入收件人电话" placeholder-style="color: #B2B2B2;" />
|
</view>
|
<view class="form-row dashed-row">
|
<text class="form-label">到店寄存时间</text>
|
<view class="row-picker" @click="showArriveTimePicker = true">
|
<text :class="form.arriveTime ? 'picker-value-text' : 'placeholder-text'">{{ form.arriveTime || '请选择' }}</text>
|
<u-icon name="arrow-right" size="18" color="#222222"></u-icon>
|
</view>
|
</view>
|
<view class="form-row no-border">
|
<text class="form-label">预计取件时间</text>
|
<view class="row-picker" @click="openPickupTimePicker">
|
<text :class="form.pickupTime ? 'picker-value-text' : 'placeholder-text'">{{ form.pickupTime || '请选择' }}</text>
|
<u-icon name="arrow-right" size="18" color="#222222"></u-icon>
|
</view>
|
</view>
|
</view>
|
<u-datetime-picker
|
:show="showArriveTimePicker"
|
v-model="arriveTimeValue"
|
mode="datetime"
|
:minDate="Date.now()"
|
confirmText="确定"
|
cancelText="取消"
|
title="选择到店寄存时间"
|
@confirm="confirmArriveTime"
|
@cancel="showArriveTimePicker = false"
|
@close="showArriveTimePicker = false"
|
></u-datetime-picker>
|
<u-datetime-picker
|
:show="showPickupTimePicker"
|
v-model="pickupTimeValue"
|
mode="datetime"
|
:minDate="pickupMinDate"
|
confirmText="确定"
|
cancelText="取消"
|
title="选择预计取件时间"
|
@confirm="confirmPickupTime"
|
@cancel="showPickupTimePicker = false"
|
@close="showPickupTimePicker = false"
|
></u-datetime-picker>
|
|
<view class="section-card luggage-card">
|
<view class="section-head between">
|
<view>
|
<text class="section-title">寄存行李类型</text>
|
<text class="section-desc">(多选,必填)</text>
|
</view>
|
<view class="price-note" @click="goRichText(9)">
|
<image class="price-note-icon" src="/static/icon/ic_tips@2x.png" mode="widthFix"></image>
|
<text>价格说明</text>
|
</view>
|
</view>
|
<view
|
v-for="(item, index) in luggageTypes"
|
:key="index"
|
class="luggage-item"
|
:class="{ active: item.count > 0 }"
|
>
|
<view class="luggage-info">
|
<view class="luggage-image">
|
<image style="height: 100%;" :src="item.iconFull" mode="heightFix"></image>
|
</view>
|
<view class="luggage-copy">
|
<text class="luggage-name">{{ item.name }}</text>
|
<text class="luggage-size">{{ item.remark || '' }}</text>
|
</view>
|
</view>
|
<view class="luggage-stepper">
|
<image class="step-btn" src="/static/icon/ic_jian@2x.png" mode="widthFix" @click="decreaseCount(index)"></image>
|
<text class="step-count">{{ item.count || 0}}</text>
|
<image class="step-btn" src="/static/icon/ic_jia@2x.png" mode="widthFix" @click="increaseCount(index)"></image>
|
</view>
|
</view>
|
</view>
|
|
<view class="section-card goods-card">
|
<view class="section-head between arrow-head" @click="showGoodsPopup = true">
|
<view>
|
<text class="section-title">物品信息</text>
|
</view>
|
<view class="required-wrap">
|
<text class="section-required goods-required-text" :style="{ color: form.goodTypeName ? '#111111' : 'red' }">{{ form.goodTypeName || '必选,请选择' }}</text>
|
<u-icon name="arrow-right" size="12" color="#A8AFBA"></u-icon>
|
</view>
|
</view>
|
<view class="goods-upload-row">
|
<view class="upload-box" @click="chooseAndUploadImage(9)">
|
<image class="upload-icon" src="/static/image/btn_upload@2x.png" mode="widthFix"></image>
|
</view>
|
<view v-for="(item, index) in uploadedImages" :key="index" class="uploaded-box">
|
<image class="uploaded-image" :src="item.url" mode="aspectFill"></image>
|
<text class="uploaded-delete" @click.stop="deleteImage(index)">删除</text>
|
</view>
|
</view>
|
</view>
|
|
<view v-if="activeMode === 'city' && amountData" class="section-card service-time-card">
|
<view class="section-head">
|
<text class="section-title">服务时效</text>
|
<text class="section-desc">(必选)</text>
|
</view>
|
<view
|
v-for="item in serviceTimes"
|
:key="item.id"
|
class="service-time-item"
|
:class="{ active: isUrgent === item.id }"
|
@tap="isUrgent = item.id"
|
>
|
<text class="service-time-name">
|
<text>{{ item.name }}</text>
|
<text>(预计{{ item.serviceTime }}小时内送达)</text>
|
</text>
|
<text class="service-time-price">¥{{ item.price }}</text>
|
</view>
|
</view>
|
|
<view class="section-card simple-card">
|
<view class="form-row no-border currency-row">
|
<text class="form-label">行李保价</text>
|
<view class="input-wrap end-wrap insurance-wrap">
|
<input v-model="form.insurance" class="form-input money-input" :class="{ 'filled-input': form.insurance }" type="digit" placeholder="必填,请输入金额" placeholder-style="color: #B2B2B2;" placeholder-class="input-placeholder" />
|
<text class="unit-text">元</text>
|
</view>
|
</view>
|
<view v-if="amountData || showInsuranceTip" class="insurance-tip-row">
|
<text v-if="showInsuranceTip" class="insurance-tip-warning">{{ showInsuranceTipText }}</text>
|
<text v-else></text>
|
<view style="display: flex; align-items: center;">
|
<text v-if="amountData" class="insurance-tip-label">物品保费:</text>
|
<text v-if="amountData" class="insurance-tip-value">¥{{ amountData.insuranceFee }}</text>
|
</view>
|
</view>
|
</view>
|
|
<view class="section-card simple-card">
|
<view class="form-row" @click="selectCoupon">
|
<text class="form-label">平台优惠券</text>
|
<view class="form-value-wrap">
|
<view style="display: flex; flex-direction: column; align-items: flex-end;">
|
<text :class="selectedCoupon && selectedCoupon.value > 0 ? 'coupon-value-red' : 'form-value-placeholder'">{{ selectedCoupon && selectedCoupon.value > 0 ? '-¥' + selectedCoupon.value.toFixed(2) : '选择优惠券' }}</text>
|
</view>
|
<u-icon name="arrow-right" size="14" color="#999999"></u-icon>
|
</view>
|
</view>
|
</view>
|
|
<view class="section-card simple-card">
|
<view class="form-row no-border">
|
<text class="form-label">备注</text>
|
<input v-model="form.remark" class="form-input" :class="{ 'filled-input': form.remark }" type="text" placeholder="请输入" placeholder-style="color: #B2B2B2;" placeholder-class="input-placeholder" />
|
</view>
|
</view>
|
|
</view>
|
<view style="width: 100%; height: 104rpx;" v-if="amountData"></view>
|
<view style="width: 100%; height: calc(112rpx + env(safe-area-inset-bottom));"></view>
|
</scroll-view>
|
|
<!-- 优惠券选择弹窗 -->
|
<u-popup :show="showCouponPopup" mode="bottom" round="24" :closeOnClickOverlay="true" @close="showCouponPopup = false">
|
<view class="coupon-popup-wrap">
|
<view class="coupon-popup-head">
|
<text class="coupon-popup-title">选择优惠券</text>
|
<view class="coupon-popup-close" @tap="showCouponPopup = false">
|
<u-icon name="close" size="28" color="#999999"></u-icon>
|
</view>
|
</view>
|
<scroll-view scroll-y class="coupon-list-scroll">
|
<template v-if="couponList.length > 0">
|
<view
|
v-for="(coupon, index) in couponList"
|
:key="index"
|
class="coupon-item"
|
:class="{ active: selectedCouponIndex === index }"
|
@click="toggleCoupon(index)"
|
>
|
<!-- 上半部分 -->
|
<view class="coupon-item-top">
|
<view class="coupon-item-left">
|
<text class="coupon-name" v-if="coupon.couponType === 0">平台满减券</text>
|
<text class="coupon-validity">有效期{{ formatDate(coupon.startDate) }}~{{ formatDate(coupon.endDate) }}</text>
|
</view>
|
<view class="coupon-item-right">
|
<text class="coupon-amount">¥{{ ((coupon.price || 0) / 100).toFixed(2) }}</text>
|
<text class="coupon-desc">满{{((coupon.limitPrice || 0) / 100).toFixed(2)}}可用</text>
|
</view>
|
</view>
|
|
<!-- 虚线分隔 -->
|
<view class="coupon-divider"></view>
|
|
<!-- 下半部分 -->
|
<view class="coupon-item-bottom">
|
<view class="coupon-usage" @click.stop="toggleUsage(index)">
|
<text class="coupon-usage-label">使用说明</text>
|
<u-icon :name="showUsageIndex === index ? 'arrow-up' : 'arrow-down'" size="14" color="#999999"></u-icon>
|
</view>
|
<u-icon v-if="selectedCouponIndex === index" name="checkmark-circle-fill" size="24" color="#1890FF"></u-icon>
|
</view>
|
|
<!-- 使用说明内容 -->
|
<view v-if="showUsageIndex === index" class="coupon-usage-content">
|
<text class="coupon-usage-text">{{ coupon.info }}</text>
|
</view>
|
</view>
|
</template>
|
<view class="coupon-list-scroll-wu" v-else>暂无优惠券</view>
|
</scroll-view>
|
<view class="coupon-confirm-btn-wrap">
|
<view class="coupon-confirm-btn active-submit-btn" @click="confirmCoupon">确定选择</view>
|
</view>
|
</view>
|
</u-popup>
|
|
<u-popup :show="showStorePopup" mode="bottom" round="24" :closeOnClickOverlay="true" @close="showStorePopup = false">
|
<view class="store-popup-wrap">
|
<view class="store-popup-head">
|
<text class="store-popup-title">{{ storePopupType === 'receive' ? '选择取件服务点' : (activeMode === 'city' ? '选择寄件服务点' : '选择服务点') }}</text>
|
<view class="store-popup-close" @tap="showStorePopup = false">
|
<u-icon name="close" size="28" color="#999999"></u-icon>
|
</view>
|
</view>
|
<view class="store-search-bar">
|
<image class="store-search-icon" src="/static/icon/ic_search2@2x.png" mode="widthFix"></image>
|
<input v-model="storeForm.keyword" class="store-search-input" type="text" @confirm="searchStore" placeholder="搜索服务点名称" placeholder-class="store-search-placeholder" />
|
</view>
|
<scroll-view scroll-y class="store-list-scroll" @scrolltolower="getNearbyShopList">
|
<view
|
v-for="(item, index) in storeList"
|
:key="index"
|
class="store-option"
|
:class="{ active: item.active }"
|
@click="storeList.forEach((row,i) => row.active = index === i)"
|
>
|
<view class="store-option-main">
|
<image class="store-thumb" :src="item.coverImg || '/static/icon/default2.png'" mode="aspectFill"></image>
|
<view class="store-option-copy">
|
<view class="store-option-head">
|
<text class="store-option-name">{{ item.name }}</text>
|
<text class="store-option-distance">{{ item.distance }}</text>
|
</view>
|
<view class="store-option-address-row">
|
<image class="store-option-address-icon" src="/static/icon/home_ic_location3@2x.png" mode="widthFix"></image>
|
<text class="store-option-address">{{ item.address }}</text>
|
</view>
|
<text class="store-option-time">{{ item.shopHours || '' }}</text>
|
</view>
|
</view>
|
<view v-if="tempSelectedStoreId === item.id" class="store-check">
|
<image src="/static/icon/ic_accept_sel@2x.png" mode="widthFix"></image>
|
</view>
|
</view>
|
</scroll-view>
|
<view class="store-confirm-btn" @tap="confirmStore">确定选择</view>
|
</view>
|
</u-popup>
|
|
<u-popup :show="showGoodsPopup" mode="bottom" round="24" :closeOnClickOverlay="true" @close="showGoodsPopup = false">
|
<view class="goods-popup-wrap">
|
<view class="goods-popup-head">
|
<text class="goods-popup-title">物品信息</text>
|
<view class="goods-popup-close" @tap="showGoodsPopup = false">
|
<u-icon name="close" size="28" color="#999999"></u-icon>
|
</view>
|
</view>
|
<view class="goods-popup-top">
|
<view class="goods-popup-title-row">
|
<text class="goods-main-title">物品名称</text>
|
<text class="goods-main-required">(必选)</text>
|
</view>
|
<view class="goods-danger-tip" @click="goRichText(10)">
|
<image class="goods-danger-icon" src="/static/icon/ic_tips@2x.png" mode="widthFix"></image>
|
<text>禁寄物品</text>
|
</view>
|
</view>
|
<text class="goods-popup-desc">为确保物品寄递安全,请检查是否不夹带易燃易爆物品</text>
|
<view style="display: block;height: 500rpx;overflow-y: auto;margin-top:10px ;">
|
<view class="goods-tag-grid">
|
<view
|
v-for="(item, index) in goodsOptions"
|
:key="index"
|
class="goods-tag"
|
:class="{ active: item.active }"
|
@click="goodsOptions.forEach((row,i) => row.active = i === index)"
|
>
|
<text>{{ item.name }}</text>
|
</view>
|
</view>
|
</view>
|
|
<view class="goods-save-btn" @tap="confirmGoods">保存</view>
|
</view>
|
</u-popup>
|
|
<u-popup :show="showAmountPopup" mode="bottom" round="24" :closeOnClickOverlay="true" @close="showAmountPopup = false">
|
<view class="amount-popup-wrap">
|
<view class="amount-popup-head">
|
<text class="amount-popup-title">金额明细</text>
|
<view class="amount-popup-close" @tap="showAmountPopup = false">
|
<u-icon name="close" size="30" color="#999999"></u-icon>
|
</view>
|
</view>
|
<view class="amount-popup-content">
|
<view v-for="(item, index) in amountData.itemList" :key="index" class="amount-row">
|
<view class="amount-row-left">
|
<text class="amount-row-label">{{ item.categoryName }}</text>
|
<text v-if="item.quantity" class="amount-row-count">x{{ item.quantity }}</text>
|
</view>
|
<text class="amount-row-value">{{ '¥' + item.unitPrice }}</text>
|
</view>
|
<view v-if="activeMode === 'city' && amountData.distance" class="amount-row amount-row-extra">
|
<view class="amount-row-left">
|
<text class="amount-row-label">配送里程</text>
|
</view>
|
<text class="amount-row-value">{{ amountData.distance + 'km' }}</text>
|
</view>
|
<view v-if="activeMode !== 'city' && amountData.days" class="amount-row amount-row-extra">
|
<view class="amount-row-left">
|
<text class="amount-row-label">寄存天数</text>
|
</view>
|
<text class="amount-row-value">{{ amountData.days + '天' }}</text>
|
</view>
|
<view v-if="amountData.insuranceFee" class="amount-row amount-row-extra">
|
<view class="amount-row-left">
|
<text class="amount-row-label">物品保费</text>
|
</view>
|
<text class="amount-row-value">{{ '¥' + amountData.insuranceFee }}</text>
|
</view>
|
<view v-if="selectedCoupon" class="amount-row amount-row-extra">
|
<view class="amount-row-left">
|
<text class="amount-row-label">平台优惠券</text>
|
</view>
|
<text class="amount-row-discount">-¥{{ selectedCoupon.value || selectedCoupon.amount || 0 }}</text>
|
</view>
|
</view>
|
<view class="agreement-bar popup-agreement-bar" @click="toggleAgreement">
|
<image class="agreement-icon" :src="agreementChecked ? '/static/icon/ic_accept_sel@2x.png' : '/static/icon/ic_accept@2x.png'" mode="widthFix" />
|
<text class="agreement-text">我已阅读并同意</text>
|
<text class="agreement-link" @tap="goRichText(0)">《用户服务协议》</text>
|
<text class="agreement-text">及</text>
|
<text class="agreement-link" @tap="goRichText(1)">《隐私政策》</text>
|
</view>
|
<view class="bottom-action-row popup-action-row">
|
<view class="total-wrap">
|
<text class="total-label">总费用</text>
|
<text class="total-price">{{ amountData ? '¥' + (amountData.totalPrice - (selectedCoupon ? selectedCoupon.value || selectedCoupon.amount || 0 : 0)).toFixed(2) : '¥--' }}</text>
|
<view style="width: 100rpx; height: 40rpx; display: flex; align-items: center;" @click="showAmountPopup = false">
|
<text class="detail-text">明细</text>
|
<u-icon name="arrow-up" size="13" color="#7B7F86"></u-icon>
|
</view>
|
</view>
|
<view class="submit-btn active-submit-btn" @click="createOrder">立即下单</view>
|
</view>
|
</view>
|
</u-popup>
|
|
<view class="bottom-bar">
|
<view class="agreement-bar" @click="toggleAgreement">
|
<image class="agreement-icon" :src="agreementChecked ? '/static/icon/ic_accept_sel@2x.png' : '/static/icon/ic_accept@2x.png'" mode="widthFix" />
|
<text class="agreement-text">我已阅读并同意</text>
|
<text class="agreement-link" @click="goRichText(0)">《用户服务协议》</text>
|
<text class="agreement-text">及</text>
|
<text class="agreement-link" @click="goRichText(1)">《隐私政策》</text>
|
</view>
|
<view class="bottom-action-row">
|
<view class="total-wrap" @click.stop="openAmountPopup">
|
<text class="total-label">总费用</text>
|
<text class="total-price">{{ amountData ? '¥' + (amountData.totalPrice - (selectedCoupon ? selectedCoupon.value || 0 : 0)).toFixed(2) : '¥--' }}</text>
|
<template v-if="amountData">
|
<text class="detail-text detail-click">明细</text>
|
<u-icon name="arrow-down" size="18" color="#999999"></u-icon>
|
</template>
|
</view>
|
<view class="submit-btn active-submit-btn" @click="createOrder">立即下单</view>
|
</view>
|
</view>
|
|
<!-- 选择服务点/地址 -->
|
<u-action-sheet
|
:show="showReceiveAddress"
|
@close="showReceiveAddress = false"
|
@select="caozuo"
|
:actions="actions"
|
:round="15"
|
cancelText="取消" />
|
</view>
|
</template>
|
|
<script>
|
import { mapState } from 'vuex'
|
export default {
|
data() {
|
return {
|
showStorePopup: false,
|
showGoodsPopup: false,
|
showAmountPopup: false,
|
showArriveTimePicker: false,
|
showPickupTimePicker: false,
|
arriveTimeValue: Number(new Date()),
|
pickupTimeValue: Number(new Date()),
|
activeMode: 'local',
|
modeTabs: [
|
{ label: '就地寄存', value: 'local' },
|
{ label: '同城寄送', value: 'city' }
|
],
|
agreementChecked: false,
|
tempSelectedStoreId: 2,
|
selectedStoreId: 2,
|
tempSelectedGoodsIds: [1],
|
selectedGoodsIds: [1],
|
selectedLuggageId: 1,
|
isUrgent: 0,
|
form: {
|
receiver: '',
|
mobile: '',
|
arriveTime: '',
|
pickupTime: '',
|
goodType: '',
|
goodTypeName: '',
|
insurance: '',
|
remark: '',
|
goodsImages: [],
|
},
|
amountData: null,
|
showInsuranceTip: false,
|
showInsuranceTipText: '',
|
luggageTypes: [],
|
serviceTimes: [],
|
|
storeList: [],
|
selectedStore: null,
|
sendStore: null,
|
receiveStore: null,
|
receiveAddr: null,
|
storePopupType: 'send',
|
storeForm: {
|
keyword: '',
|
page: 1,
|
isSearch: true
|
},
|
|
goodsOptions: [],
|
uploadedImages: [],
|
|
showReceiveAddress: false,
|
actions: [
|
{ name: '选择服务点' },
|
{ name: '选择地址簿' }
|
],
|
selectedCoupon: null,
|
showCouponPopup: false,
|
couponList: [],
|
selectedCouponIndex: -1,
|
showUsageIndex: -1,
|
}
|
},
|
watch: {
|
'form.insurance': {
|
handler() {
|
this.calculateLocalPrice()
|
}
|
},
|
isUrgent: {
|
handler() {
|
if (this.activeMode === 'city') {
|
this.calculateRemotePrice()
|
}
|
}
|
}
|
},
|
computed: {
|
...mapState(['latitude', 'longitude', 'cityId', 'statusbarHeight', 'navHeight', 'userInfo']),
|
servicePointPlaceholder() {
|
return this.activeMode === 'city' ? '选择寄送服务点' : '选择寄存服务点'
|
},
|
selectedGoodsText() {
|
if (!this.selectedGoodsIds.length) {
|
return '必选,请选择'
|
}
|
const labels = this.goodsOptions
|
.filter(item => this.selectedGoodsIds.includes(item.id))
|
.map(item => item.name)
|
return labels.join('、')
|
},
|
totalPriceText() {
|
return '¥150.00'
|
},
|
pickupMinDate() {
|
if (this.form.arriveTime) {
|
return new Date(this.form.arriveTime).getTime()
|
}
|
return Date.now()
|
}
|
},
|
onLoad() {
|
this.getNearbyShopList()
|
this.getCategoryList()
|
this.getCitySizeList()
|
this.agreementChecked=false
|
this.getContactInfo()
|
|
if (uni.getStorageSync('selectedStore')) {
|
const store = uni.getStorageSync('selectedStore')
|
this.selectedStore = store
|
this.sendStore = store
|
uni.removeStorageSync('selectedStore')
|
}
|
|
uni.$on('updateAddress', (data) => {
|
this.receiveStore = null
|
this.form.receiver = data.name
|
this.form.mobile = data.phone
|
this.receiveAddr = data
|
this.receiveAddr.addr = data.provinceName + data.cityName + data.districtName + data.addr
|
})
|
|
uni.$on('selectCoupon', (data) => {
|
this.selectedCoupon = data
|
if (this.activeMode === 'city') {
|
this.calculateRemotePrice()
|
} else {
|
this.calculateLocalPrice()
|
}
|
})
|
},
|
onUnload() {
|
uni.$off('updateAddress')
|
uni.$off('selectCoupon')
|
},
|
methods: {
|
formatDate(dateStr) {
|
if (!dateStr) return ''
|
const date = new Date(dateStr)
|
const year = String(date.getFullYear()).slice(2)
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
const day = String(date.getDate()).padStart(2, '0')
|
const hours = String(date.getHours()).padStart(2, '0')
|
const minutes = String(date.getMinutes()).padStart(2, '0')
|
return `${year}.${month}.${day} ${hours}:${minutes}`
|
},
|
hasFormData() {
|
if (this.form.receiver || this.form.mobile || this.form.arriveTime ||
|
this.form.pickupTime || this.form.goodType || this.form.insurance ||
|
this.form.remark || this.form.goodsImages.length > 0 ||
|
this.selectedStore || this.sendStore || this.receiveStore ||
|
this.receiveAddr || this.amountData) {
|
return true
|
}
|
if (this.luggageTypes.some(item => item.count > 0)) {
|
return true
|
}
|
return false
|
},
|
goBack() {
|
if (this.hasFormData()) {
|
uni.showModal({
|
title: '提示',
|
content: '离开后当前页面内容失效,是否确认离开?',
|
confirmText: '确认离开',
|
cancelText: '取消',
|
success: (res) => {
|
if (res.confirm) {
|
uni.navigateBack()
|
}
|
}
|
})
|
} else {
|
uni.navigateBack()
|
}
|
},
|
getCouponId() {
|
if (this.selectedCoupon && this.selectedCoupon.id && this.selectedCoupon.id > 0) {
|
return this.selectedCoupon.id
|
} else if (this.selectedCoupon && this.selectedCoupon.id === 0) {
|
return null
|
}
|
return -1
|
},
|
selectCoupon() {
|
this.showCouponPopup = true
|
},
|
toggleUsage(index) {
|
if (this.showUsageIndex === index) {
|
this.showUsageIndex = -1
|
} else {
|
this.showUsageIndex = index
|
}
|
},
|
toggleCoupon(index) {
|
if (this.selectedCouponIndex === index) {
|
// 重复点击,取消选择
|
this.selectedCouponIndex = -1
|
} else {
|
// 选择优惠券
|
this.selectedCouponIndex = index
|
}
|
},
|
confirmCoupon() {
|
if (this.selectedCouponIndex >= 0 && this.selectedCouponIndex < this.couponList.length) {
|
const coupon = this.couponList[this.selectedCouponIndex]
|
this.selectedCoupon = {
|
id: coupon.id,
|
name: coupon.name,
|
value: coupon.value || coupon.amount / 100,
|
price: coupon.amount
|
}
|
this.showCouponPopup = false
|
if (this.activeMode === 'city') {
|
this.calculateRemotePrice()
|
} else {
|
this.calculateLocalPrice()
|
}
|
} else if (this.selectedCouponIndex === -1) {
|
// 取消选择优惠券
|
this.selectedCoupon = { id: 0, name: '不使用优惠券', value: 0 }
|
this.showCouponPopup = false
|
if (this.activeMode === 'city') {
|
this.calculateRemotePrice()
|
} else {
|
this.calculateLocalPrice()
|
}
|
}
|
},
|
caozuo(e) {
|
var that = this;
|
if (e.name === '选择服务点') {
|
that.storePopupType = 'receive'
|
that.showStorePopup = true
|
} else if (e.name === '选择地址簿') {
|
uni.navigateTo({
|
url: '/pages/address/address?type=1'
|
})
|
}
|
this.showReceiveAddress = false
|
},
|
async uploadFiles(filePaths, maxCount = 9) {
|
if (!filePaths || filePaths.length === 0) {
|
return []
|
}
|
const limitedPaths = filePaths.slice(0, maxCount)
|
const uploadTasks = limitedPaths.map(filePath => {
|
return new Promise((resolve, reject) => {
|
uni.uploadFile({
|
url: this.$baseUrl + '/web/public/upload',
|
filePath: filePath,
|
name: 'file',
|
formData: {
|
folder: 'orders'
|
},
|
success: (res) => {
|
if (res.statusCode === 200) {
|
const data = JSON.parse(res.data)
|
if (data.code === 200) {
|
resolve(data.data)
|
} else {
|
reject(new Error(data.msg || '上传失败'))
|
}
|
} else {
|
reject(new Error('上传失败'))
|
}
|
},
|
fail: (err) => {
|
reject(err)
|
}
|
})
|
})
|
})
|
try {
|
const results = await Promise.all(uploadTasks)
|
return results
|
} catch (error) {
|
uni.showToast({
|
title: '上传失败',
|
icon: 'none'
|
})
|
throw error
|
}
|
},
|
deleteImage(index) {
|
this.uploadedImages.splice(index, 1)
|
this.form.goodsImages.splice(index, 1)
|
},
|
async chooseAndUploadImage(maxCount = 9) {
|
const currentCount = this.form.goodsImages.length
|
const remainingCount = maxCount - currentCount
|
if (remainingCount <= 0) {
|
uni.showToast({
|
title: `最多上传${maxCount}张图片`,
|
icon: 'none'
|
})
|
return
|
}
|
uni.chooseImage({
|
count: remainingCount,
|
sizeType: ['compressed'],
|
sourceType: ['album', 'camera'],
|
success: async (res) => {
|
const tempFilePaths = res.tempFilePaths
|
uni.showLoading({
|
title: '上传中...',
|
mask: true
|
})
|
try {
|
const uploadResults = await this.uploadFiles(tempFilePaths, maxCount)
|
const addrs = uploadResults.map(item => item.imgaddr)
|
const fullPaths = uploadResults.map(item => item.url || item.path || item)
|
this.uploadedImages = [...this.uploadedImages, ...fullPaths.map(url => ({ url }))]
|
this.form.goodsImages = [...this.form.goodsImages, ...addrs]
|
uni.hideLoading()
|
uni.showToast({
|
title: '上传成功',
|
icon: 'success'
|
})
|
} catch (error) {
|
uni.hideLoading()
|
}
|
}
|
})
|
},
|
searchStore() {
|
this.storeList = []
|
this.storeForm.page = 1
|
this.storeForm.isSearch = true
|
this.getNearbyShopList()
|
},
|
switchMode(mode) {
|
this.activeMode = mode
|
this.receiveStore = null
|
this.receiveAddr = null
|
this.form.arriveTime = ''
|
this.form.pickupTime = ''
|
this.form.goodType = ''
|
this.form.goodTypeName = ''
|
this.form.insurance = ''
|
this.form.remark = ''
|
this.form.goodsImages = []
|
this.amountData = null
|
this.uploadedImages = []
|
this.luggageTypes.forEach(item => {
|
item.count = 0
|
})
|
},
|
toggleAgreement() {
|
this.agreementChecked = !this.agreementChecked
|
},
|
goRichText(type) {
|
uni.navigateTo({
|
url: '/pages/rich-text/rich-text?type=' + type
|
})
|
},
|
openReceiveAddress() {
|
this.showReceiveAddress = true
|
},
|
openAmountPopup() {
|
this.showAmountPopup = true
|
},
|
openStorePopup() {
|
this.storePopupType = 'send'
|
this.tempSelectedStoreId = null
|
this.showStorePopup = true
|
},
|
openStorePopup0() {
|
this.storePopupType = 'send0'
|
this.tempSelectedStoreId = null
|
this.showStorePopup = true
|
},
|
confirmStore() {
|
|
console.log("=========================")
|
const selected = this.storeList.find(item => item.active)
|
console.log(selected)
|
if (this.storePopupType === 'send') {
|
this.sendStore = selected
|
} else if (this.storePopupType === 'receive') {
|
this.receiveStore = selected
|
this.receiveAddr = null
|
this.calculateRemotePrice()
|
} else {
|
this.selectedStore = selected
|
this.calculateLocalPrice()
|
}
|
this.showStorePopup = false
|
},
|
confirmGoods() {
|
if (!this.goodsOptions.find(item => item.active)) {
|
uni.showToast({ title: '请选择物品信息', icon: 'none' })
|
return
|
}
|
this.form.goodTypeName = this.goodsOptions.find(item => item.active)?.name || ''
|
this.form.goodType = this.goodsOptions.find(item => item.active)?.id || ''
|
this.showInsuranceTip = this.goodsOptions.find(item => item.active)?.relationOtherField === '1'
|
this.showInsuranceTipText = this.goodsOptions.find(item => item.active)?.relationRemark
|
this.showGoodsPopup = false
|
},
|
confirmArriveTime(e) {
|
const date = new Date(e.value)
|
const year = date.getFullYear()
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
const day = String(date.getDate()).padStart(2, '0')
|
const hour = String(date.getHours()).padStart(2, '0')
|
const minute = String(date.getMinutes()).padStart(2, '0')
|
this.form.arriveTime = `${year}-${month}-${day} ${hour}:${minute}`
|
this.form.pickupTime = ''
|
this.pickupTimeValue = e.value + 3600000
|
this.showArriveTimePicker = false
|
this.calculateLocalPrice()
|
},
|
openPickupTimePicker() {
|
if (!this.form.arriveTime) {
|
uni.showToast({ title: '请先选择到店寄存时间', icon: 'none' })
|
return
|
}
|
this.showPickupTimePicker = true
|
},
|
confirmPickupTime(e) {
|
const date = new Date(e.value)
|
const year = date.getFullYear()
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
const day = String(date.getDate()).padStart(2, '0')
|
const hour = String(date.getHours()).padStart(2, '0')
|
const minute = String(date.getMinutes()).padStart(2, '0')
|
const pickupTime = `${year}-${month}-${day} ${hour}:${minute}`
|
if (this.form.arriveTime && new Date(pickupTime) <= new Date(this.form.arriveTime)) {
|
uni.showToast({ title: '预计取件时间必须大于到店寄存时间', icon: 'none' })
|
return
|
}
|
this.form.pickupTime = pickupTime
|
this.showPickupTimePicker = false
|
this.calculateLocalPrice()
|
},
|
// 物品分类
|
async getCategoryList() {
|
const res = await this.$u.api.getCategoryList({ type: 2 })
|
if (res.code === 200) {
|
res.data.forEach(item => {
|
item.active = false
|
})
|
this.goodsOptions = res.data || []
|
}
|
},
|
async getCitySizeList() {
|
const res = await this.$u.api.getCitySizeList({ cityId: this.cityId })
|
if (res.code === 200) {
|
res.data.forEach(item => {
|
item.count = 0
|
})
|
this.luggageTypes = res.data || []
|
}
|
},
|
async getContactInfo() {
|
const res = await this.$u.api.getContactInfo({})
|
if (res.code === 200 && res.data) {
|
this.form.receiver = res.data.name || this.userInfo.name || ''
|
this.form.mobile = res.data.phone || this.userInfo.telephone || ''
|
} else {
|
this.form.receiver = this.userInfo.name || ''
|
this.form.mobile = this.userInfo.telephone || ''
|
}
|
},
|
async getNearbyShopList() {
|
if (!this.storeForm.isSearch) return;
|
const res = await this.$u.api.getNearbyShopList({
|
capacity: 10,
|
page: this.storeForm.page,
|
model: {
|
latitude: this.latitude,
|
longitude: this.longitude,
|
cityId: this.cityId,
|
name:this.storeForm.keyword,
|
sortType: 1
|
}
|
})
|
if (res.code === 200) {
|
res.data.records.forEach(item => {
|
item.active = false
|
})
|
this.storeList = [...this.storeList, ...res.data.records || []]
|
this.storeForm.page++
|
this.storeForm.isSearch = this.storeList.length <= res.data.total
|
}
|
},
|
increaseCount(index) {
|
this.luggageTypes[index].count++
|
this.calculateLocalPrice()
|
},
|
decreaseCount(index) {
|
if (this.luggageTypes[index].count > 0) {
|
this.luggageTypes[index].count--
|
}
|
this.calculateLocalPrice()
|
},
|
async calculateLocalPrice() {
|
if (this.activeMode === 'city') {
|
this.calculateRemotePrice()
|
} else {
|
this.calculateLocalPriceOnly()
|
}
|
},
|
async calculateLocalPriceOnly() {
|
if (!this.form.arriveTime || !this.form.pickupTime) {
|
this.amountData = null
|
return
|
}
|
const luggageList = this.luggageTypes
|
.filter(item => item.count > 0)
|
.map(item => ({
|
categoryId: item.id,
|
quantity: item.count
|
}))
|
if (luggageList.length === 0) {
|
this.amountData = null
|
return
|
}
|
const res = await this.$u.api.calculateLocalPrice({
|
cityId: this.cityId,
|
depositStartTime: this.form.arriveTime + ':00',
|
depositEndTime: this.form.pickupTime + ':00',
|
items: luggageList,
|
declaredAmount: this.form.insurance || 0,
|
couponId: this.getCouponId()
|
})
|
if (res.code === 200) {
|
res.data.itemList.forEach(item => {
|
item.unitPrice = item.unitPrice / 100
|
})
|
res.data.totalPrice = res.data.totalPrice / 100
|
res.data.insuranceFee = res.data.insuranceFee / 100
|
if (res.data.selectedCoupon) {
|
res.data.selectedCoupon.value = res.data.selectedCoupon.price / 100
|
}
|
if (res.data.availableCoupons) {
|
res.data.availableCoupons.forEach(coupon => {
|
coupon.value = coupon.price / 100
|
})
|
this.couponList = res.data.availableCoupons
|
}
|
this.amountData = res.data
|
if (res.data.selectedCoupon) {
|
this.selectedCoupon = res.data.selectedCoupon
|
// 找到对应的优惠券索引
|
if (res.data.availableCoupons) {
|
const index = res.data.availableCoupons.findIndex(coupon => coupon.id === res.data.selectedCoupon.id)
|
if (index !== -1) {
|
this.selectedCouponIndex = index
|
}
|
}
|
}
|
}
|
},
|
async calculateRemotePrice() {
|
if (!this.sendStore) {
|
this.amountData = null
|
return
|
}
|
if (!this.receiveStore && !this.receiveAddr) {
|
this.amountData = null
|
return
|
}
|
const luggageList = this.luggageTypes
|
.filter(item => item.count > 0)
|
.map(item => ({
|
categoryId: item.id,
|
quantity: item.count
|
}))
|
if (luggageList.length === 0) {
|
this.amountData = null
|
return
|
}
|
let fromLat = ''
|
let fromLgt = ''
|
let toLat = ''
|
let toLgt = ''
|
if (this.sendStore) {
|
fromLat = this.sendStore.latitude
|
fromLgt = this.sendStore.longitude
|
}
|
if (this.receiveStore) {
|
toLat = this.receiveStore.latitude
|
toLgt = this.receiveStore.longitude
|
} else if (this.receiveAddr) {
|
toLat = this.receiveAddr.latitude
|
toLgt = this.receiveAddr.longitude
|
}
|
const res = await this.$u.api.calculateRemotePrice({
|
cityId: this.cityId,
|
fromLat: fromLat,
|
fromLgt: fromLgt,
|
toLat: toLat,
|
toLgt: toLgt,
|
urgent: this.isUrgent,
|
items: luggageList,
|
declaredAmount: this.form.insurance || 0,
|
couponId: this.getCouponId()
|
})
|
if (res.code === 200) {
|
res.data.itemList.forEach(item => {
|
item.unitPrice = item.unitPrice / 100
|
})
|
res.data.totalPrice = res.data.totalPrice / 100
|
res.data.insuranceFee = res.data.insuranceFee / 100
|
if (res.data.selectedCoupon) {
|
res.data.selectedCoupon.value = res.data.selectedCoupon.price / 100
|
}
|
if (res.data.availableCoupons) {
|
res.data.availableCoupons.forEach(coupon => {
|
coupon.value = coupon.price / 100
|
})
|
this.couponList = res.data.availableCoupons
|
}
|
this.serviceTimes = [
|
{ id: 0, name: '标准达', serviceTime: res.data.standardHours, price: res.data.itemPrice / 100 },
|
{ id: 1, name: '急速达', serviceTime: res.data.urgentHours, price: (res.data.urgentFee + res.data.itemPrice) / 100 }
|
]
|
this.amountData = res.data
|
if (res.data.selectedCoupon) {
|
this.selectedCoupon = res.data.selectedCoupon
|
// 找到对应的优惠券索引
|
if (res.data.availableCoupons) {
|
const index = res.data.availableCoupons.findIndex(coupon => coupon.id === res.data.selectedCoupon.id)
|
if (index !== -1) {
|
this.selectedCouponIndex = index
|
}
|
}
|
}
|
}
|
},
|
async createOrder() {
|
if (this.activeMode === 'local') {
|
if (!this.selectedStore) {
|
uni.showToast({ title: '请选择门店', icon: 'none' })
|
return
|
}
|
} else {
|
if (!this.sendStore) {
|
uni.showToast({ title: '请选择寄件服务点', icon: 'none' })
|
return
|
}
|
if (!this.receiveStore && !this.receiveAddr) {
|
uni.showToast({ title: '请选择取件地址', icon: 'none' })
|
return
|
}
|
}
|
if (!this.form.receiver) {
|
uni.showToast({ title: '请输入收件人姓名', icon: 'none' })
|
return
|
}
|
if (!this.form.mobile) {
|
uni.showToast({ title: '请输入收件人电话', icon: 'none' })
|
return
|
}
|
const mobileRegex = /^1\d{10}$/
|
const landlineRegex = /^\d{3,4}-?\d{7,8}$/
|
if (!mobileRegex.test(this.form.mobile) && !landlineRegex.test(this.form.mobile)) {
|
uni.showToast({ title: '请输入正确的手机号或固定电话', icon: 'none' })
|
return
|
}
|
if (!this.form.arriveTime) {
|
uni.showToast({ title: '请选择到店寄存时间', icon: 'none' })
|
return
|
}
|
if (!this.form.pickupTime) {
|
uni.showToast({ title: '请选择预计取件时间', icon: 'none' })
|
return
|
}
|
if (new Date(this.form.pickupTime) <= new Date(this.form.arriveTime)) {
|
uni.showToast({ title: '预计取件时间必须大于到店寄存时间', icon: 'none' })
|
return
|
}
|
const luggageList = this.luggageTypes
|
.filter(item => item.count > 0)
|
.map(item => ({
|
categoryId: item.id,
|
quantity: item.count
|
}))
|
if (luggageList.length === 0) {
|
uni.showToast({ title: '请选择行李类型', icon: 'none' })
|
return
|
}
|
if (!this.form.goodType) {
|
uni.showToast({ title: '请选择物品信息', icon: 'none' })
|
return
|
}
|
if (!this.form.goodsImages ||!this.form.goodsImages.length) {
|
uni.showToast({ title: '请上传物品照片', icon: 'none' })
|
return
|
}
|
if (!this.form.goodsImages ||!this.form.goodsImages.length) {
|
uni.showToast({ title: '请上传物品照片', icon: 'none' })
|
return
|
}
|
if (this.form.insurance === '' || this.form.insurance <= 0) {
|
uni.showToast({ title: '请输入保价费', icon: 'none' })
|
return
|
}
|
if (!this.agreementChecked) {
|
uni.showToast({ title: '请先阅读并同意用户服务协议及隐私政策', icon: 'none' })
|
return
|
}
|
const items = luggageList.map(item => ({
|
categoryId: item.categoryId,
|
quantity: item.quantity
|
}))
|
let orderParams = {
|
cityId: this.cityId,
|
declaredAmount: this.form.insurance || 0,
|
expectedDepositTime: this.form.arriveTime + ':00',
|
expectedTakeTime: this.form.pickupTime + ':00',
|
goodType: this.form.goodType,
|
goodsImages: this.form.goodsImages,
|
items: items,
|
remark: this.form.remark,
|
takePhone: this.form.mobile,
|
takeUser: this.form.receiver,
|
type: this.activeMode === 'local' ? 0 : 1,
|
isUrgent: this.isUrgent,
|
couponId: this.getCouponId()
|
}
|
if (this.activeMode === 'local') {
|
orderParams.depositShopId = this.selectedStore.id
|
} else {
|
orderParams.depositShopId = this.sendStore.id
|
orderParams.fromShopId = this.sendStore.id
|
if (this.receiveStore) {
|
orderParams.toType = 0
|
orderParams.takeShopId = this.receiveStore.id
|
orderParams.takeLat = this.receiveStore.latitude
|
orderParams.takeLgt = this.receiveStore.longitude
|
orderParams.takeLocation = this.receiveStore.address
|
} else if (this.receiveAddr) {
|
orderParams.toType = 1
|
orderParams.toAddrId = this.receiveAddr.id
|
orderParams.takeLat = this.receiveAddr.latitude
|
orderParams.takeLgt = this.receiveAddr.longitude
|
orderParams.takeLocation = this.receiveAddr.addr
|
}
|
}
|
const res = await this.$u.api.createOrder(orderParams)
|
if (res.code === 200) {
|
if (res.data) {
|
this.processPayment(res.data.response, res.data.orderId)
|
}
|
}
|
},
|
processPayment(paymentData, orderId) {
|
uni.requestPayment({
|
provider: 'wxpay',
|
timeStamp: paymentData.timeStamp || '',
|
nonceStr: paymentData.nonceStr || '',
|
package: paymentData.package || '',
|
signType: paymentData.signType || 'MD5',
|
paySign: paymentData.paySign || '',
|
success: (res) => {
|
uni.redirectTo({
|
url: '/pages/payment-success/payment-success?orderId=' + orderId
|
});
|
},
|
fail: (err) => {
|
if (err.errMsg.includes('cancel')) {
|
uni.showToast({ title: '已取消支付', icon: 'none' })
|
} else {
|
uni.showToast({ title: '支付失败', icon: 'none' })
|
}
|
uni.setStorageSync("orderStatus",-2)
|
uni.switchTab({
|
url: '/pages/itinerary/itinerary'
|
});
|
|
}
|
})
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.luggage-page {
|
position: relative;
|
min-height: 100vh;
|
background: #f5f6f8;
|
}
|
|
.nav-bar {
|
position: sticky;
|
top: 0;
|
left: 0;
|
right: 0;
|
background: #ffffff;
|
z-index: 100;
|
.nav-content {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
padding: 0 30rpx;
|
.nav-left {
|
width: 40rpx;
|
height: 40rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
.nav-title {
|
font-size: 34rpx;
|
font-weight: 600;
|
color: #333333;
|
}
|
.nav-right {
|
width: 40rpx;
|
}
|
}
|
}
|
|
.top-gradient-bg {
|
position: absolute;
|
left: 0;
|
top: 0;
|
width: 100%;
|
height: 480rpx;
|
background: linear-gradient(180deg, #15b9f7 0%, #f7f7f7 100%);
|
z-index: 0;
|
}
|
|
.mode-tabs {
|
height: 88rpx;
|
background: #ffffff;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
position: relative;
|
z-index: 1;
|
border-bottom: 1rpx solid #f0f0f0;
|
}
|
|
.mode-tab {
|
position: relative;
|
width: 50%;
|
text-align: center;
|
font-weight: 600;
|
font-size: 32rpx;
|
color: #9097a3;
|
}
|
|
.mode-tab.active {
|
color: #222222;
|
}
|
|
.mode-line {
|
position: absolute;
|
left: 50%;
|
bottom: -28rpx;
|
width: 40rpx;
|
height: 6rpx;
|
border-radius: 6rpx;
|
background: #18b5ff;
|
transform: translateX(-50%);
|
}
|
|
.page-scroll {
|
position: relative;
|
height: calc(100vh - 88rpx - 186rpx - env(safe-area-inset-bottom));
|
}
|
|
.page-content {
|
padding: 22rpx 30rpx;
|
box-sizing: border-box;
|
}
|
|
.store-popup-wrap {
|
background: #ffffff;
|
border-radius: 24rpx 24rpx 0 0;
|
padding: 0 30rpx 16rpx 30rpx;
|
box-sizing: border-box;
|
}
|
|
.store-popup-head {
|
position: relative;
|
height: 96rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
|
.store-popup-title {
|
font-weight: 600;
|
font-size: 32rpx;
|
color: #222222;
|
}
|
|
.store-popup-close {
|
position: absolute;
|
right: 0;
|
top: 50%;
|
transform: translateY(-50%);
|
width: 56rpx;
|
height: 56rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
|
.store-search-bar {
|
height: 74rpx;
|
padding: 0 20rpx;
|
background: #f6f8fc;
|
border-radius: 14rpx;
|
display: flex;
|
align-items: center;
|
}
|
|
.store-search-icon {
|
width: 32rpx;
|
height: 32rpx;
|
margin-right: 16rpx;
|
}
|
|
.store-search-input {
|
flex: 1;
|
height: 74rpx;
|
font-size: 26rpx;
|
color: #333333;
|
background: transparent;
|
}
|
|
.store-search-placeholder {
|
font-size: 26rpx;
|
color: #c1c6d0;
|
}
|
|
.store-list-scroll {
|
max-height: 60vh;
|
min-height: 50vh;
|
margin-top: 30rpx;
|
}
|
|
.store-option {
|
position: relative;
|
padding: 30rpx;
|
box-sizing: border-box;
|
margin-bottom: 20rpx;
|
border-radius: 16rpx;
|
background: #F6F9FF;
|
border: 2rpx solid transparent;
|
box-sizing: border-box;
|
}
|
|
.store-option.active {
|
background: #eef9ff;
|
border-color: #10B2FA;
|
}
|
|
.store-option-main {
|
display: flex;
|
align-items: center;
|
}
|
|
.store-thumb {
|
width: 140rpx;
|
height: 140rpx;
|
border-radius: 8rpx;
|
background: #e8edf5;
|
margin-right: 30rpx;
|
flex-shrink: 0;
|
overflow: hidden;
|
}
|
|
.store-option-copy {
|
flex: 1;
|
min-width: 0;
|
}
|
|
.store-option-head {
|
display: flex;
|
align-items: flex-start;
|
justify-content: space-between;
|
gap: 12rpx;
|
}
|
|
.store-option-name {
|
flex: 1;
|
font-size: 34rpx;
|
font-weight: 600;
|
line-height: 1.35;
|
color: #222222;
|
}
|
|
.store-option-distance {
|
font-size: 26rpx;
|
color: #9ea4af;
|
flex-shrink: 0;
|
}
|
|
.store-option-address-row {
|
margin-top: 8rpx;
|
display: flex;
|
align-items: flex-start;
|
flex-wrap: wrap;
|
}
|
|
.store-option-address-icon {
|
flex-shrink: 0;
|
width: 24rpx;
|
height: 24rpx;
|
margin-right: 4rpx;
|
margin-top: 6rpx;
|
}
|
|
.store-option-address {
|
flex: 1;
|
font-size: 26rpx;
|
color: #9ea4af;
|
}
|
|
.store-option-time {
|
display: block;
|
margin-top: 8rpx;
|
font-size: 26rpx;
|
color: #9ea4af;
|
}
|
|
.store-check {
|
position: absolute;
|
right: 18rpx;
|
bottom: 18rpx;
|
width: 40rpx;
|
height: 40rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
image {
|
width: 100%;
|
}
|
}
|
|
.store-confirm-btn {
|
height: 74rpx;
|
margin-top: 20rpx;
|
border-radius: 37rpx;
|
background: linear-gradient(90deg, #1db6ff 0%, #16a9fa 100%);
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
font-size: 32rpx;
|
font-weight: 600;
|
color: #ffffff;
|
}
|
|
.cell-card,
|
.section-card {
|
background: #ffffff;
|
border-radius: 16rpx;
|
}
|
|
.service-point-card {
|
padding: 30rpx;
|
box-sizing: border-box;
|
display: flex;
|
align-items: flex-start;
|
justify-content: space-between;
|
border-radius: 16rpx;
|
}
|
|
.cell-left {
|
display: flex;
|
align-items: flex-start;
|
min-width: 0;
|
}
|
|
.store-cell-copy {
|
min-width: 0;
|
display: flex;
|
flex-direction: column;
|
justify-content: center;
|
}
|
|
.store-cell-copy-addr1 {
|
display: flex;
|
align-items: baseline;
|
image {
|
width: 24rpx;
|
height: 24rpx;
|
margin-right: 4rpx;
|
}
|
}
|
|
.store-cell-copy-addr {
|
display: flex;
|
flex-direction: column;
|
.store-cell-subtitle-container {
|
display: flex;
|
align-items: center;
|
image {
|
flex-shrink: 0;
|
width: 24rpx;
|
height: 24rpx;
|
margin-right: 4rpx;
|
}
|
}
|
}
|
|
.with-icon .cell-icon {
|
width: 40rpx;
|
height: 40rpx;
|
margin-right: 16rpx;
|
}
|
|
.cell-title {
|
font-weight: 600;
|
font-size: 30rpx;
|
color: #222222;
|
line-height: 1.3;
|
}
|
|
.cell-title.placeholder {
|
color: #9097a3;
|
font-weight: 400;
|
}
|
|
.store-cell-subtitle {
|
margin-top: 8rpx;
|
font-weight: 400;
|
font-size: 24rpx;
|
color: #999999;
|
white-space: nowrap;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
}
|
|
.address-card {
|
padding: 32rpx 30rpx;
|
box-sizing: border-box;
|
margin-top: 0 !important;
|
}
|
|
.address-row {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
margin-bottom: 42rpx;
|
&:last-child {
|
margin-bottom: 0 !important;
|
}
|
}
|
|
.address-left {
|
display: flex;
|
align-items: flex-start;
|
min-width: 0;
|
}
|
|
.address-badge {
|
width: 38rpx;
|
height: 38rpx;
|
border-radius: 19rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
font-size: 22rpx;
|
font-weight: 600;
|
color: #ffffff;
|
margin-right: 18rpx;
|
flex-shrink: 0;
|
}
|
|
.address-badge.send {
|
background: #2ab6ff;
|
}
|
|
.address-badge.receive {
|
background: #ff9528;
|
}
|
|
.address-copy {
|
min-width: 0;
|
display: flex;
|
flex-direction: column;
|
justify-content: center;
|
}
|
|
.address-title {
|
font-weight: 600;
|
font-size: 30rpx;
|
color: #222222;
|
}
|
|
.address-desc {
|
margin-top: 10rpx;
|
font-weight: 400;
|
font-size: 24rpx;
|
color: #999999;
|
white-space: nowrap;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
}
|
|
.section-card {
|
margin-top: 16rpx;
|
overflow: hidden;
|
}
|
|
.info-card,
|
.time-card,
|
.simple-card {
|
padding: 0 30rpx;
|
box-sizing: border-box;
|
}
|
|
.section-head {
|
display: flex;
|
align-items: center;
|
padding: 24rpx 0 12rpx;
|
}
|
|
.section-head.between {
|
justify-content: space-between;
|
}
|
|
.arrow-head {
|
align-items: center;
|
}
|
|
.section-title {
|
font-weight: 600;
|
font-size: 32rpx;
|
color: #222222;
|
}
|
|
.section-desc,
|
.section-required {
|
font-weight: 400;
|
font-size: 24rpx;
|
color: #999999;
|
}
|
|
.price-note {
|
display: flex;
|
align-items: center;
|
font-size: 22rpx;
|
color: #ff8a32;
|
}
|
|
.price-note-icon {
|
width: 28rpx;
|
height: 28rpx;
|
margin-right: 10rpx;
|
}
|
|
.required-wrap {
|
display: flex;
|
align-items: center;
|
gap: 8rpx;
|
}
|
|
.form-row {
|
height: 104rpx;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
border-bottom: 1rpx solid #E5E5E5;
|
}
|
|
.form-row.no-border {
|
border-bottom: none;
|
}
|
|
.form-row.dashed-row {
|
border-bottom: 1rpx dashed #d8d8d8;
|
}
|
|
.form-label {
|
font-weight: 500;
|
font-size: 30rpx;
|
color: #222222;
|
}
|
|
.form-value-wrap {
|
display: flex;
|
align-items: center;
|
gap: 8rpx;
|
flex: 1;
|
justify-content: flex-end;
|
}
|
|
.form-value-text {
|
font-weight: 400;
|
font-size: 28rpx;
|
color: #333333;
|
}
|
|
.form-value-placeholder {
|
font-weight: 400;
|
font-size: 28rpx;
|
color: #B2B2B2;
|
}
|
|
.form-input {
|
flex: 1;
|
height: 88rpx;
|
text-align: right;
|
font-weight: 400;
|
font-size: 28rpx;
|
color: #333333;
|
background: transparent;
|
}
|
|
.filled-input {
|
color: #333333;
|
}
|
|
.input-placeholder,
|
.placeholder-text {
|
font-weight: 400;
|
font-size: 28rpx;
|
color: #B2B2B2;
|
}
|
|
.picker-value-text {
|
font-weight: 400;
|
font-size: 28rpx;
|
color: #333333;
|
}
|
|
.row-picker,
|
.end-wrap {
|
display: flex;
|
align-items: center;
|
justify-content: flex-end;
|
gap: 8rpx;
|
flex: 1;
|
}
|
|
.luggage-card {
|
padding: 0 16rpx 16rpx;
|
}
|
|
.luggage-item {
|
display: flex;
|
align-items: flex-end;
|
justify-content: space-between;
|
padding: 24rpx;
|
box-sizing: border-box;
|
margin-top: 20rpx;
|
border-radius: 16rpx;
|
background: #fafafa;
|
border: 2rpx solid transparent;
|
}
|
|
.luggage-item.active {
|
background: #f5fbff;
|
border-color: #28aef8;
|
}
|
|
.luggage-info {
|
display: flex;
|
align-items: center;
|
min-width: 0;
|
}
|
|
.luggage-image {
|
width: 100rpx;
|
height: 100rpx;
|
border-radius: 8rpx;
|
margin-right: 18rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
background: #f0f1f4;
|
overflow: hidden;
|
margin-right: 24rpx;
|
}
|
|
.luggage-copy {
|
height: 100rpx;
|
display: flex;
|
flex-direction: column;
|
justify-content: space-between;
|
}
|
|
.luggage-name {
|
font-size: 30rpx;
|
font-weight: 500;
|
color: #333333;
|
}
|
|
.luggage-size {
|
margin-top: 8rpx;
|
font-size: 22rpx;
|
color: #b7bcc5;
|
}
|
|
.luggage-stepper {
|
display: flex;
|
align-items: center;
|
gap: 18rpx;
|
}
|
|
.step-btn {
|
width: 44rpx;
|
height: 44rpx;
|
}
|
|
.step-count {
|
font-size: 28rpx;
|
color: #555555;
|
}
|
|
.goods-card {
|
padding: 0 24rpx 24rpx;
|
}
|
|
.upload-box {
|
width: 144rpx;
|
height: 144rpx;
|
}
|
|
.goods-upload-row {
|
display: flex;
|
align-items: center;
|
flex-wrap: wrap;
|
gap: 12rpx;
|
margin-top: 8rpx;
|
}
|
|
.uploaded-box {
|
width: 144rpx;
|
height: 144rpx;
|
border-radius: 8rpx;
|
overflow: hidden;
|
position: relative;
|
background: #f2f4f8;
|
}
|
|
.uploaded-image {
|
width: 100%;
|
height: 100%;
|
}
|
|
.uploaded-delete {
|
position: absolute;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
height: 40rpx;
|
line-height: 40rpx;
|
text-align: center;
|
font-weight: 400;
|
font-size: 24rpx;
|
color: #FFFFFF;
|
background: rgba(0,0,0,0.5);
|
border-radius: 0rpx 0rpx 8rpx 8rpx;
|
}
|
|
.service-time-card {
|
padding: 0 24rpx 24rpx;
|
box-sizing: border-box;
|
}
|
|
.service-time-item {
|
height: 88rpx;
|
margin-top: 20rpx;
|
padding: 0 30rpx;
|
border-radius: 14rpx;
|
background: #f6f6f6;
|
border: 2rpx solid transparent;
|
box-sizing: border-box;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
}
|
|
.service-time-item.active {
|
background: #eef9ff;
|
border-color: #10B2FA;
|
}
|
|
.service-time-name {
|
display: flex;
|
align-items: center;
|
text {
|
&:nth-child(1) {
|
font-weight: 600;
|
font-size: 30rpx;
|
color: #222222;
|
}
|
&:nth-child(2) {
|
font-weight: 400;
|
font-size: 24rpx;
|
color: #222222;
|
}
|
}
|
}
|
|
.service-time-price {
|
font-weight: 600;
|
font-size: 30rpx;
|
color: #FF0000;
|
}
|
|
.upload-icon {
|
width: 100%;
|
height: 100%;
|
}
|
|
.upload-text {
|
font-size: 22rpx;
|
color: #b0b5be;
|
}
|
|
.goods-required-text {
|
max-width: 300rpx;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
white-space: nowrap;
|
}
|
|
.goods-popup-wrap {
|
background: #ffffff;
|
border-radius: 24rpx 24rpx 0 0;
|
padding: 0 30rpx;
|
box-sizing: border-box;
|
}
|
|
.goods-popup-head {
|
position: relative;
|
height: 96rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
|
.goods-popup-title {
|
font-weight: 600;
|
font-size: 32rpx;
|
color: #222222;
|
}
|
|
.goods-popup-close {
|
position: absolute;
|
right: 0;
|
top: 50%;
|
transform: translateY(-50%);
|
width: 56rpx;
|
height: 56rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
|
.goods-popup-top {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
}
|
|
.goods-popup-title-row {
|
display: flex;
|
align-items: center;
|
}
|
|
.goods-main-title {
|
font-weight: bold;
|
font-size: 30rpx;
|
color: #222222;
|
}
|
|
.goods-main-required {
|
font-weight: 400;
|
font-size: 24rpx;
|
color: #FF0000;
|
}
|
|
.goods-danger-tip {
|
display: flex;
|
align-items: center;
|
font-weight: 400;
|
font-size: 24rpx;
|
color: #FA8010;
|
}
|
|
.goods-danger-icon {
|
width: 28rpx;
|
height: 28rpx;
|
margin-right: 10rpx;
|
}
|
|
.goods-popup-desc {
|
display: block;
|
margin-top: 18rpx;
|
font-weight: 400;
|
font-size: 24rpx;
|
color: #999999;
|
}
|
|
.goods-tag-grid {
|
display: grid;
|
grid-template-columns: repeat(3, 1fr);
|
gap: 18rpx 16rpx;
|
margin-top: 28rpx;
|
}
|
|
.goods-tag {
|
height: 72rpx;
|
background: #F7F7F7;
|
border-radius: 36rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
font-size: 28rpx;
|
font-weight: 500;
|
color: #333333;
|
border: 2rpx solid transparent;
|
white-space: nowrap; /* 防止文本换行 */
|
overflow: hidden; /* 隐藏溢出的内容 */
|
text-overflow: ellipsis; /* 显示省略号来代表被修剪的文本 */
|
box-sizing: border-box;
|
}
|
|
.goods-tag.active {
|
background: #ecf8ff;
|
border-color: #10B2FA;
|
color: #10B2FA;
|
}
|
|
.goods-save-btn {
|
height: 88rpx;
|
background: #10B2FA;
|
border-radius: 44rpx;
|
margin: 46rpx 0 0;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
font-weight: bold;
|
font-size: 32rpx;
|
color: #FFFFFF;
|
}
|
|
.amount-popup-wrap {
|
background: #ffffff;
|
border-radius: 24rpx 24rpx 0 0;
|
overflow: hidden;
|
}
|
|
.amount-popup-head {
|
position: relative;
|
height: 96rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
|
.amount-popup-title {
|
font-weight: 600;
|
font-size: 32rpx;
|
color: #222222;
|
}
|
|
.amount-popup-close {
|
position: absolute;
|
right: 24rpx;
|
top: 50%;
|
transform: translateY(-50%);
|
width: 56rpx;
|
height: 56rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
|
.amount-popup-content {
|
padding: 8rpx 0 12rpx;
|
}
|
|
.amount-row {
|
height: 80rpx;
|
padding: 0 30rpx;
|
box-sizing: border-box;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
}
|
|
.amount-row-left {
|
display: flex;
|
align-items: center;
|
}
|
|
.amount-row-label {
|
font-weight: 400;
|
font-size: 30rpx;
|
color: #222222;
|
}
|
|
.amount-row-count {
|
margin-left: 18rpx;
|
font-weight: 400;
|
font-size: 30rpx;
|
color: #222222;
|
}
|
|
.amount-row-value {
|
font-weight: 400;
|
font-size: 30rpx;
|
color: #222222;
|
}
|
|
.amount-row-right {
|
display: flex;
|
align-items: center;
|
gap: 8rpx;
|
}
|
|
.amount-row-placeholder {
|
font-weight: 400;
|
font-size: 30rpx;
|
color: #999999;
|
}
|
|
.amount-row-discount {
|
font-weight: 400;
|
font-size: 30rpx;
|
color: #FF4D4F;
|
}
|
|
.popup-agreement-bar {
|
margin-top: 12rpx;
|
}
|
|
.popup-action-row {
|
padding-bottom: calc(16rpx + env(safe-area-inset-bottom));
|
}
|
|
.money-input {
|
max-width: 260rpx;
|
}
|
|
.insurance-wrap {
|
gap: 10rpx;
|
}
|
|
.unit-text {
|
font-size: 28rpx;
|
color: #666666;
|
}
|
|
.insurance-tip-row {
|
height: 48rpx;
|
padding-bottom: 14rpx;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
font-size: 22rpx;
|
}
|
|
.insurance-tip-label {
|
color: #999999;
|
}
|
|
.insurance-tip-warning {
|
color: #ff4d4f;
|
font-size: 22rpx;
|
font-weight: 400;
|
}
|
|
.insurance-tip-value {
|
margin-left: 8rpx;
|
color: #ff4d4f;
|
}
|
|
.agreement-bar {
|
height: 80rpx;
|
padding: 0 16rpx;
|
background: #d9f3ff;
|
display: flex;
|
align-items: center;
|
flex-wrap: wrap;
|
font-size: 22rpx;
|
box-sizing: border-box;
|
}
|
|
.agreement-icon {
|
width: 40rpx;
|
height: 40rpx;
|
margin-right: 16rpx;
|
}
|
|
.agreement-text {
|
color: #7c8e97;
|
}
|
|
.agreement-link {
|
color: #10b2fa;
|
}
|
|
.bottom-bar {
|
position: fixed;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
z-index: 1;
|
padding: 0 0 env(safe-area-inset-bottom);
|
background: #ffffff;
|
box-sizing: border-box;
|
box-shadow: 0 -6rpx 18rpx rgba(0, 0, 0, 0.05);
|
}
|
|
.bottom-action-row {
|
height: 112rpx;
|
padding: 16rpx 20rpx;
|
box-sizing: border-box;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
}
|
|
.total-wrap {
|
display: flex;
|
align-items: baseline;
|
gap: 8rpx;
|
}
|
|
.total-label,
|
.detail-text {
|
font-weight: 400;
|
font-size: 26rpx;
|
color: #999999;
|
}
|
|
.detail-click {
|
padding: 6rpx 0;
|
}
|
|
.total-price {
|
font-weight: 600;
|
font-size: 36rpx;
|
color: #FF0000;
|
}
|
|
.submit-btn {
|
width: 240rpx;
|
height: 88rpx;
|
border-radius: 44rpx;
|
background: #d9d9d9;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
font-weight: bold;
|
font-size: 32rpx;
|
color: #FFFFFF;
|
}
|
|
.active-submit-btn {
|
background: #10B2FA;
|
}
|
|
/* 优惠券弹窗样式 */
|
.coupon-popup-wrap {
|
background: #ffffff;
|
border-radius: 24rpx 24rpx 0 0;
|
padding: 0 30rpx 16rpx 30rpx;
|
box-sizing: border-box;
|
}
|
|
.coupon-popup-head {
|
position: relative;
|
height: 96rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
|
.coupon-popup-title {
|
font-weight: 600;
|
font-size: 32rpx;
|
color: #222222;
|
}
|
|
.coupon-popup-close {
|
position: absolute;
|
right: 0;
|
top: 50%;
|
transform: translateY(-50%);
|
width: 56rpx;
|
height: 56rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
|
.coupon-list-scroll {
|
max-height: 60vh;
|
min-height: 20vh;
|
padding-bottom: 20rpx;
|
}
|
|
.coupon-list-scroll-wu {
|
width: 100%;
|
height: 20vh;
|
line-height: 20vh;
|
text-align: center;
|
font-weight: 400;
|
font-size: 30rpx;
|
color: #999999;
|
}
|
|
.coupon-item {
|
background: #F7F8FA;
|
border-radius: 16rpx;
|
padding: 24rpx;
|
margin-bottom: 16rpx;
|
display: flex;
|
flex-direction: column;
|
gap: 20rpx;
|
border: 2rpx solid transparent;
|
transition: all 0.3s;
|
}
|
|
.coupon-item-top {
|
display: flex;
|
justify-content: space-between;
|
align-items: flex-start;
|
}
|
|
.coupon-item-bottom {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
}
|
|
.coupon-divider {
|
height: 1rpx;
|
background: repeating-linear-gradient(to right, #CCCCCC 0, #CCCCCC 8rpx, transparent 8rpx, transparent 16rpx);
|
margin: 12rpx 0;
|
}
|
|
.coupon-item.active {
|
background: #E6F7FF;
|
border-color: #1890FF;
|
}
|
|
.coupon-item-left {
|
flex: 1;
|
display: flex;
|
flex-direction: column;
|
gap: 12rpx;
|
}
|
|
.coupon-name {
|
font-weight: 500;
|
font-size: 30rpx;
|
color: #222222;
|
}
|
|
.coupon-validity {
|
font-weight: 400;
|
font-size: 24rpx;
|
color: #999999;
|
}
|
|
.coupon-usage {
|
display: flex;
|
align-items: center;
|
gap: 8rpx;
|
font-weight: 400;
|
font-size: 24rpx;
|
color: #666666;
|
}
|
|
.coupon-usage-label {
|
font-weight: 400;
|
font-size: 24rpx;
|
color: #666666;
|
}
|
|
.coupon-usage-content {
|
|
}
|
|
.coupon-usage-text {
|
font-weight: 400;
|
font-size: 24rpx;
|
color: #666666;
|
line-height: 1.5;
|
}
|
|
.coupon-item-right {
|
display: flex;
|
flex-direction: column;
|
align-items: flex-end;
|
gap: 12rpx;
|
}
|
|
.coupon-amount {
|
font-weight: 600;
|
font-size: 32rpx;
|
color: #FF4D4F;
|
}
|
|
.coupon-desc {
|
font-weight: 400;
|
font-size: 22rpx;
|
color: #FF4D4F;
|
border-radius: 12rpx;
|
}
|
|
.coupon-confirm-btn-wrap {
|
padding: 24rpx 0;
|
}
|
|
.coupon-confirm-btn {
|
height: 88rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
font-weight: bold;
|
font-size: 32rpx;
|
color: #FFFFFF;
|
border-radius: 44rpx;
|
}
|
|
.coupon-value-red {
|
font-weight: 400;
|
font-size: 30rpx;
|
color: #FF4D4F;
|
}
|
</style>
|