1155 lines
33 KiB
Vue
1155 lines
33 KiB
Vue
<template>
|
||
<view class="order-wrap" :class="[`${themeInfo.theme}-theme`]">
|
||
<navBar></navBar>
|
||
<view class="container">
|
||
<view class="box1">
|
||
<view class="topBox">
|
||
<view class="info">
|
||
<!-- <view class="span"></view> -->
|
||
<view class="info-left">
|
||
{{ state.lockData.name }}
|
||
</view>
|
||
<view class="info-right">
|
||
<view class="text"
|
||
>{{ $t("detail.store") }}:{{ state.lockData.siteName }}</view
|
||
>
|
||
<view class="text"
|
||
>{{ $t("detail.unit") }}:{{
|
||
state.lockData.unitTypeName
|
||
}}</view
|
||
>
|
||
<view class="text"
|
||
>{{ $t("detail.spec") }}:{{ removeTrailingZeros(state.lockData.length) }}m *
|
||
{{ removeTrailingZeros(state.lockData.width) }}m * {{ removeTrailingZeros(state.lockData.height) }}m</view
|
||
>
|
||
<view class="text"
|
||
>{{ $t("detail.size") }}:{{ state.lockData.volume }} m³.</view>
|
||
</view>
|
||
</view>
|
||
<view class="pirce">
|
||
<view class="left"> {{ currency }} {{ state.priceData.originalPrice }} </view>
|
||
<view class="right">
|
||
<!-- $ {{state.lockData.currentPrice}} -->
|
||
{{ currency }} {{ state.priceData.price }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="box2">
|
||
<view class="left">
|
||
<view class="left1">
|
||
{{ $t("detail.sitemap") }}
|
||
</view>
|
||
<view class="left2">
|
||
{{ $t("detail.selected") }}
|
||
</view>
|
||
</view>
|
||
<view class="right">
|
||
<uv-image
|
||
class="right-image"
|
||
width="406rpx"
|
||
height="342rpx"
|
||
@click="showImage(baseImageUrl + state.lockData.lockerImageUrl)"
|
||
:src="baseImageUrl + state.lockData.lockerImageUrl"
|
||
altr="no img"
|
||
mode=""
|
||
></uv-image>
|
||
</view>
|
||
</view>
|
||
<view class="box3">
|
||
<view class="select">
|
||
<view class="label"> * {{ $t("detail.cUnit") }} </view>
|
||
<view class="inputBox">
|
||
<view class="value">
|
||
{{ state.lockData.unitTypeName }}
|
||
</view>
|
||
<view class="arrow"> </view>
|
||
</view>
|
||
</view>
|
||
<view class="select">
|
||
<view class="label"> * {{ $t("detail.startDate") }} </view>
|
||
<view class="inputBox">
|
||
<view class="value">
|
||
{{ dayjs(state.rentalEndDate).format("YYYY/MM/DD") }}
|
||
</view>
|
||
<view class="arrow">
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="select">
|
||
<view class="label"> * {{ $t("detail.lease") }} </view>
|
||
<view class="inputBox" @click="showMonthPicker">
|
||
<view class="value">
|
||
{{ state.month }}
|
||
</view>
|
||
<view class="arrow">
|
||
<button>
|
||
{{ $t("common.more") }} <image style="margin-left: 20rpx;" src="/static/setOrder/selectArrow.png" mode=""></image>
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="monthSelect" v-if="state.lockData.discountList">
|
||
<view
|
||
v-for="(item, index) in state.lockData.discountList"
|
||
class="month"
|
||
:key="index"
|
||
:class="index == selectMonthIndex ? 'active' : ''"
|
||
@click="monthChange(item.month, index)"
|
||
>
|
||
{{
|
||
$t("detail.discountOff", {
|
||
month: item.month,
|
||
percent: 100 - (item.discount * 100),
|
||
discount: item.discount * 100 / 10,
|
||
})
|
||
}}
|
||
<image src="../../static/setOrder/fire.png" v-if="index == 0"></image>
|
||
</view>
|
||
</view>
|
||
<view class="fee">
|
||
<view class="info">
|
||
<view class="left">
|
||
{{ $t("detail.rentalFee") }}
|
||
</view>
|
||
<view class="right"> {{ currency }} {{ state.priceData.discountExpense }} </view>
|
||
</view>
|
||
<view class="info">
|
||
<view class="left">
|
||
{{ $t("detail.cDeposit") }}
|
||
</view>
|
||
<view class="right"> {{ currency }} {{ state.priceData.securityDeposit }} </view>
|
||
</view>
|
||
</view>
|
||
<!-- 额外需求 -->
|
||
<!-- <view class="select">
|
||
<view class="label"> * {{ $t("detail.cValueAdded") }} </view>
|
||
<view class="inputBox">
|
||
<view class="value">
|
||
{{ $t("detail.nodata") }}
|
||
</view>
|
||
<view class="arrow">
|
||
<image src="/static/setOrder/selectArrow.png" mode=""></image>
|
||
</view>
|
||
</view>
|
||
</view> -->
|
||
<view class="select" @click="openCoupon">
|
||
<view class="label"> * {{ $t("detail.coupon") }} </view>
|
||
<view class="inputBox">
|
||
<view class="value">
|
||
<template v-if="state.couponOtherItem.length">
|
||
<template v-for="(item, index) in state.couponOtherItem" :key="index">
|
||
<!-- {{ item.platform }} {{ item.marketPrice }} -->
|
||
{{ item.title }}
|
||
</template>
|
||
<template v-if="!state.couponItem.length &&!state.couponOtherItem.length">,</template>
|
||
</template>
|
||
<template v-for="(item, index) in state.couponItem" :key="index">{{item.couponCode }} {{ couponDesc(item) }} </template>
|
||
<!-- {{$t("detail.noselect") }} -->
|
||
<template v-if="!state.couponItem.length &&!state.couponOtherItem.length">{{
|
||
$t("detail.noselect")
|
||
}}</template>
|
||
</view>
|
||
<view class="arrow">
|
||
<view @click.stop.prevent="clearCoupon" style="padding: 0rpx 10rpx;"><uv-icon name="close-circle"></uv-icon></view>
|
||
<button>
|
||
{{ $t("common.more") }} <image style="margin-left: 20rpx;" src="/static/setOrder/selectArrow.png" mode=""></image>
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="select points" v-if="state.priceData?.maxPoint>0">
|
||
<view class="label" style="color: black;"> * {{ $t("detail.PointsRedemption") }} <text style="font-size: 22rpx;">({{ $t('detail.AvailablePoints') }}:{{ state.priceData?.maxPoint }})</text></view>
|
||
<view class="inputBox" style="display: block;">
|
||
<view class="value">
|
||
<!-- <uv-slider customStyle="width: 100%;" :show-value="true" v-model="state.point" :min="0" :max="state.priceData?.maxPoint" @change="pointsChange"></uv-slider> -->
|
||
<!-- <uv-number-box :inputWidth="60" :integer="true" :min="0"></uv-number-box><text>当前拥有:10076</text> -->
|
||
<uv-number-box :inputWidth="60" :integer="true" :min="0" v-model="state.point" :max="state.priceData?.maxPoint" @change="pointsChange"></uv-number-box>
|
||
</view>
|
||
<view style="text-align: center;color: red;">
|
||
{{$t('detail.DeductionAmount')}}:{{ currency }} {{ state.priceData?.deductionMoney }}
|
||
</view>
|
||
<!-- <view class="arrow">
|
||
<button>
|
||
{{ $t("common.reset") }}
|
||
</button>
|
||
<button>
|
||
{{ $t("common.Max") }}
|
||
</button>
|
||
</view> -->
|
||
</view>
|
||
</view>
|
||
<view class="select" v-if="state.priceData.isExpansion">
|
||
<view class="info">
|
||
<view class="left">
|
||
{{ $t("giftMonth",{count:state.priceData.giveExtraMonth})}}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 项目估值 -->
|
||
<!-- <view class="select">
|
||
<view class="label">
|
||
* {{ $t("detail.valuation") }}
|
||
</view>
|
||
<view class="garyBox">
|
||
<view class="left">
|
||
¥ 200
|
||
</view>
|
||
<view class="right">
|
||
{{ $t("detail.currency") }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="tips">
|
||
{{ $t("detail.extraTip") }}
|
||
</view>-->
|
||
<view class="select">
|
||
<view class="label"> * {{ $t("detail.feeDetail") }} </view>
|
||
<view class="info">
|
||
<view class="left">
|
||
{{ $t("detail.rentalFee") }}
|
||
</view>
|
||
<view class="right"> {{ currency }} {{ state.priceData.lockerExpense }} </view>
|
||
</view>
|
||
<view class="info">
|
||
<view class="left">
|
||
{{ $t("detail.deposit") }}
|
||
</view>
|
||
<view class="right"> {{ currency }} {{ state.priceData.securityDeposit }} </view>
|
||
</view>
|
||
<view class="info">
|
||
<view class="left">
|
||
{{ $t("detail.valueAdded") }}
|
||
</view>
|
||
<view class="right"> {{ currency }} 0.00 </view>
|
||
</view>
|
||
<view class="info">
|
||
<view class="left">
|
||
{{ $t("detail.discount") }}
|
||
</view>
|
||
<view class="right"> {{ currency }} {{ state.priceData.favorable }} </view>
|
||
</view>
|
||
<view class="info" v-if="state.priceData.couponPrice>0">
|
||
<view class="left">
|
||
{{ $t("common.tuangouCouponPrice") }}
|
||
</view>
|
||
<view class="right"> {{ currency }} {{ state.priceData.couponPrice }} </view>
|
||
</view>
|
||
<view class="info Total">
|
||
<view class="left">
|
||
{{ $t("detail.total") }}
|
||
</view>
|
||
<view class="right"> {{ currency }} {{ state.priceData.expense }} </view>
|
||
</view>
|
||
</view>
|
||
<view class="bth">
|
||
<button class="next-btn" @click="next">
|
||
{{ $t("unlock.renew") }}
|
||
</button>
|
||
</view>
|
||
<!-- <view class="agreed" >
|
||
<view class="check-wrap" @click="changeCheck" :class="{ checked: state.checked }"></view>
|
||
<view>
|
||
<text class="read">{{ $t("detail.read") }}</text>
|
||
<text class="stress" @click="openFile">{{ $t("detail.agreement") }}</text>
|
||
</view>
|
||
</view> -->
|
||
</view>
|
||
<uv-picker
|
||
ref="picker"
|
||
:confirmText="$t('common.confirm')"
|
||
:cancelText="$t('common.cancel')"
|
||
:columns="columns"
|
||
keyName="label"
|
||
@confirm="onMonthConfirm"
|
||
></uv-picker>
|
||
<uv-calendars
|
||
ref="calendars"
|
||
:start-date="state.minDate"
|
||
:confirmText="$t('common.confirm')"
|
||
:cancelText="$t('common.cancel')"
|
||
:end-date="state.maxDate"
|
||
@confirm="calendarConfirm"
|
||
/>
|
||
|
||
<uv-popup
|
||
ref="popup"
|
||
customStyle="width: 80%; height: 400rpx; padding:50rpx 0; border-radius: 32rpx; display: flex; flex-direction: column; justify-content: center; align-items: center;"
|
||
>
|
||
<text>{{ $t("common.bindPhone") }}</text>
|
||
<text style="padding: 0 40rpx; margin-top: 20rpx; text-align: center;">{{ $t('common.bindPhoneAfter') }}</text>
|
||
<!-- #ifdef MP-WEIXIN -->
|
||
<button
|
||
style="width: 80%; margin-top: 20px; background: #5BBC6B; color: #FFFFFF; line-height: 80rpx;"
|
||
open-type="getPhoneNumber"
|
||
@getphonenumber="getPhoneNumber"
|
||
>
|
||
{{ $t("common.QuickBind") }}
|
||
</button>
|
||
<!-- #endif -->
|
||
</uv-popup>
|
||
<myModal
|
||
v-model="state.showPayAfterMoadl"
|
||
:cancelShow="false"
|
||
@confirm="payAfterconfirm"
|
||
>
|
||
<view class="payAfter">
|
||
<view class="payAfterIcon" style="display: flex;justify-content: center;">
|
||
<uv-icon
|
||
:name="
|
||
state.paySuccessOrfail
|
||
? 'checkmark-circle-fill'
|
||
: 'close-circle-fill'
|
||
"
|
||
:color="state.paySuccessOrfail ? '#14b51a' : '#f10526'"
|
||
size="60"
|
||
></uv-icon>
|
||
</view>
|
||
<view class="payAfterText">
|
||
{{
|
||
state.paySuccessOrfail
|
||
? $t("common.paySuccess")
|
||
: $t("common.payFail")
|
||
}}
|
||
</view>
|
||
</view>
|
||
</myModal>
|
||
<!-- 优惠卷 -->
|
||
<coupon
|
||
ref="couponRef"
|
||
v-model="state.couponShow"
|
||
:priceData="state.priceData"
|
||
:month="state.month"
|
||
:couponItem="state.couponItem"
|
||
:couponOtherItem="state.couponOtherItem"
|
||
:isRenew="true"
|
||
:siteData="state.lockData"
|
||
:disabledFunc="disabledFunc"
|
||
@chooseOtherCoupon="chooseOtherCoupon"
|
||
@chooseCoupon="chooseCoupon"
|
||
@confirm="confirmCoupon"
|
||
></coupon>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, watchEffect,watch } from "vue";
|
||
import navBar from "@/components/navBar.vue";
|
||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||
import { useSiteApi } from "@/Apis/site.js";
|
||
import { useOrderApi } from "@/Apis/order.js";
|
||
import { useLoginApi } from "@/Apis/login.js";
|
||
import { removeTrailingZeros } from "@/utils/common.js";
|
||
import coupon from '@/components/coupon.vue';
|
||
import dayjs from "dayjs";
|
||
import { baseImageUrl,setOrderDays,currency } from "@/config/index.js";
|
||
// 主题色配置
|
||
import { useMainStore } from "@/store/index.js";
|
||
import { useI18n } from "vue-i18n";
|
||
import myModal from "@/components/myModal.vue";
|
||
const { themeInfo, getUserInfo } = useMainStore();
|
||
const { t } = useI18n();
|
||
const picker = ref();
|
||
const calendars = ref();
|
||
const getApi = useSiteApi();
|
||
const getLoginApi = useLoginApi();
|
||
const getOrderApi = useOrderApi();
|
||
const checked = ref(true);
|
||
const couponRef = ref();
|
||
const popup = ref();
|
||
const columns = ref([]);
|
||
columns.value[0] = Array.from({ length: 36 }, (v, i) => ({
|
||
label: t(i + 1 > 1 ? "months" : "month", { count: i + 1 }),
|
||
id: i + 1,
|
||
}));
|
||
const showImage = (url) => {
|
||
uni.previewImage({
|
||
urls: [url],
|
||
});
|
||
};
|
||
const payAfterconfirm = () => {
|
||
if (state.value.paySuccessOrfail) {
|
||
uni.reLaunch({
|
||
url: "/pages/unlock/index",
|
||
});
|
||
}
|
||
};
|
||
const clearCoupon = () => {
|
||
state.value.couponItem = [];
|
||
state.value.couponOtherItem = [];
|
||
state.value.point = 0;
|
||
getLockerExpense();
|
||
};
|
||
|
||
const confirmCoupon = (data)=>{
|
||
const { couponItem, couponOtherItem } = data;
|
||
state.value.couponItem = couponItem;
|
||
state.value.couponOtherItem = couponOtherItem;
|
||
getLockerExpense();
|
||
couponRef.value.close();
|
||
}
|
||
|
||
const chooseCoupon = (item)=>{
|
||
// 可以叠加就添加
|
||
if(item.isSuperposition){
|
||
if(state.value.couponItem.every((x)=>item.couponDispositionId != x.couponDispositionId)){
|
||
if(state.value.couponItem.every(x=>item.couponType != x.couponType)){
|
||
state.value.couponItem.push(item);
|
||
}else{
|
||
uni.showToast({
|
||
title: `相同优惠卷类型不能叠加使用!`,
|
||
icon: "none",
|
||
duration: 2000,
|
||
})
|
||
}
|
||
}
|
||
}else{
|
||
state.value.couponItem = [item]
|
||
}
|
||
getLockerExpense()
|
||
}
|
||
const openFile = () => {
|
||
if (state.value.lockData.agreementUrl) {
|
||
// #ifdef MP-WEIXIN
|
||
// 下载 打开文件
|
||
uni.downloadFile({
|
||
url: state.value.lockData.agreementUrl,
|
||
success: (res) => {
|
||
if (res.statusCode === 200) {
|
||
uni.openDocument({
|
||
filePath: res.tempFilePath,
|
||
success: function (res) {
|
||
console.log("打开文档成功");
|
||
},
|
||
});
|
||
}
|
||
},
|
||
});
|
||
// #endif
|
||
// #ifdef H5
|
||
uni.navigateTo({
|
||
url:
|
||
"/pages/webview/web?url=" +
|
||
encodeURIComponent(state.value.lockData.agreementUrl),
|
||
});
|
||
// #endif
|
||
} else {
|
||
uni.showToast({
|
||
title: "暂无协议",
|
||
icon: "none",
|
||
});
|
||
}
|
||
};
|
||
const today = dayjs()
|
||
.set("hour", 0)
|
||
.set("minute", 0)
|
||
.set("second", 0)
|
||
.set("millisecond", 0);
|
||
// 生成当天一个月后的日期
|
||
let oneMonthLater = today.add(setOrderDays, "day");
|
||
|
||
const chooseOtherCoupon= (item) => {
|
||
state.value.couponOtherItem = [item];
|
||
getLockerExpense();
|
||
}
|
||
const state = ref({
|
||
checked: true,
|
||
lockerId: "",
|
||
orderId: "",
|
||
rentalEndDate: today.format("YYYY/MM/DD"),
|
||
minDate: today.format("YYYY/MM/DD"),
|
||
maxDate: oneMonthLater.format("YYYY/MM/DD"),
|
||
month: 24,
|
||
lockData: {},
|
||
orderData: {},
|
||
priceData: {},
|
||
showPayAfterMoadl: false, //打开支付窗口
|
||
paySuccessOrfail: false, // 支付状态
|
||
couponShow:false, // 优惠卷窗口
|
||
couponItem:[], // 优惠卷
|
||
couponOtherItem:[],
|
||
point: 0,
|
||
|
||
});
|
||
|
||
// 如果当前最多使用积分 大于所选的置零
|
||
watch(()=>state.value.priceData?.maxPoint,()=>{
|
||
if(state.value.priceData?.maxPoint>state.value.point){
|
||
state.value.point = 0
|
||
getLockerExpense()
|
||
}
|
||
})
|
||
|
||
|
||
function canAddValue(arr, value) {
|
||
// 定义可以共存的数字
|
||
const allowedNumbers = new Set([1, 3, 4]);
|
||
|
||
// 如果数组为空,可以添加任意值
|
||
if (arr.length === 0) {
|
||
return true;
|
||
}
|
||
|
||
// 检查数组中是否已经存在非1、3、4的值
|
||
const hasInvalidNumber = arr.some(num => !allowedNumbers.has(num));
|
||
if (hasInvalidNumber) {
|
||
return false; // 如果数组中已经有非1、3、4的值,不能添加任何值
|
||
}
|
||
|
||
// 如果要添加的值是1、3、4,且没有重复,则可以添加
|
||
if (allowedNumbers.has(value) && !arr.includes(value)) {
|
||
return true;
|
||
}
|
||
|
||
// 其他情况不能添加
|
||
return false;
|
||
}
|
||
const disabledFunc = (item)=>{
|
||
if(!item) {return true}
|
||
// item.siteIds 空的时候 包括全部
|
||
const isSite = item.siteIds.length?item.siteIds.includes(state.value.lockData.siteId):true
|
||
const isUnit = item.unitTypeIds.length?item.unitTypeIds.includes(state.value.lockData.unitTypeId):true
|
||
let isPrice = item.satisfyAmount?state.value.priceData.expense>=item.satisfyAmount:true
|
||
const canAdd = canAddValue(state.value.couponItem.map(x=>x.couponType),item.couponType)
|
||
if([3,4,5,6].includes(item.couponType)){
|
||
isPrice = state.value.month>=item.fullMonth
|
||
}
|
||
|
||
// 将日期字符串转换为 Date 对象
|
||
const start = new Date(item.startDate);
|
||
const end = new Date(item.endDate);
|
||
// 获取当前日期和时间
|
||
const now = new Date();
|
||
// 判断当前日期是否在开始日期和结束日期之间
|
||
const isDate = now >= start && now <= end;
|
||
return !(isSite&&isUnit&&isPrice&&item.renewUsable&&isDate&&canAdd)
|
||
}
|
||
const openCoupon = ()=>{
|
||
couponRef.value.open();
|
||
}
|
||
const showMonthPicker = () => {
|
||
picker.value.open();
|
||
};
|
||
const showCalendar = () => {
|
||
calendars.value.open();
|
||
};
|
||
const changeCheck = () => {
|
||
state.value.checked = !state.value.checked;
|
||
};
|
||
const calendarConfirm = (e) => {
|
||
state.value.startDate = dayjs(e.fulldate).format("YYYY/MM/DD");
|
||
};
|
||
const onMonthConfirm = (e) => {
|
||
state.value.month = e.value[0].id;
|
||
clearCoupon();
|
||
};
|
||
const selectMonthIndex = ref(0);
|
||
const monthChange = (num, index) => {
|
||
state.value.month = num;
|
||
selectMonthIndex.value = index;
|
||
clearCoupon();
|
||
};
|
||
|
||
// 1) 防抖定时器 + 请求序号(只认最后一次)
|
||
let pointDebounceTimer = null
|
||
// 2) change 回调:拿到最新值,先写回,再防抖触发计算
|
||
const pointsChange = (e) => {
|
||
// 兼容:e 可能是 number,也可能是 { value: number }
|
||
const newPoint = typeof e.value === 'number' ? e : (e?.value ?? state.value.point)
|
||
|
||
// 确保 state 里是最新值(避免 change 时 v-model 还没同步完)
|
||
state.value.point = newPoint
|
||
|
||
clearTimeout(pointDebounceTimer)
|
||
pointDebounceTimer = setTimeout(() => {
|
||
getLockerExpense()
|
||
}, 250) // 200~400ms 都可以
|
||
}
|
||
|
||
|
||
watchEffect(() => {
|
||
let discountList = state.value.lockData.discountList;
|
||
if (!discountList?.length) return;
|
||
let firstIndex = discountList.findIndex(item => state.value.month >= item.month);
|
||
selectMonthIndex.value = firstIndex;
|
||
});
|
||
onLoad((params) => {
|
||
state.value.lockerId = params.lockerId;
|
||
state.value.orderId = params.orderId;
|
||
});
|
||
onShow(() => {
|
||
getLockerById();
|
||
});
|
||
// 根据优惠卷类型 返回优惠卷 作用范围 优惠多少钱 打多少折 首页多少钱
|
||
const couponDesc = (item)=>{
|
||
let detail = ''
|
||
switch(item.couponType){
|
||
case 1:
|
||
detail = `${t('discountMomey',{discount:item.discountLimit})}`
|
||
break
|
||
case 2:
|
||
detail = `${t('couponDiscount',{percent: 100 - item.discountRange * 100,discount: (item.discountRange * 100) / 10,})}`
|
||
break
|
||
case 3:
|
||
detail = `${t('firstMonthRent',{discount:item.firstMonthAmount})}`
|
||
break
|
||
case 4:
|
||
detail = `${t('couponDiscount',{percent: 100 - item.monthDiscount * 100,discount: (item.monthDiscount * 100) / 10})}`
|
||
break
|
||
case 5:
|
||
detail = `${t('freeMonth',{discount:item.freeMonth})}`
|
||
break
|
||
case 6:
|
||
detail = `${t('BonusMonth',{discount:item.freeMonth})}`
|
||
break
|
||
default:
|
||
detail = `${t('discountMomey',{discount:item.discountLimit})}`
|
||
break
|
||
}
|
||
return `${detail}`
|
||
}
|
||
const phoneNumber = ref("");
|
||
function getPhoneNumber(e) {
|
||
uni.showLoading();
|
||
phoneNumber.value = e.detail.code;
|
||
if (e.detail.code) {
|
||
getLoginApi.GetPhoneNumber({code:e.detail.code}).then((res) => {
|
||
if (res.code == 200) {
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: "获取手机号成功",
|
||
icon: "none",
|
||
duration: 2000,
|
||
});
|
||
popup.value.close();
|
||
}
|
||
});
|
||
} else {
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: "获取手机号失败",
|
||
icon: "none",
|
||
duration: 2000,
|
||
});
|
||
}
|
||
}
|
||
const GetOrderById = () => {
|
||
getOrderApi.GetOrderById({ orderId: state.value.orderId }).then((res) => {
|
||
uni.hideLoading();
|
||
if (res.code === 200) {
|
||
state.value.rentalEndDate = res.data.rentalEndDate;
|
||
}
|
||
});
|
||
};
|
||
const getLockerById = () => {
|
||
uni.showLoading();
|
||
getApi.GetLockerById({ lockerId: state.value.lockerId }).then((res) => {
|
||
if (res.code === 200) {
|
||
state.value.lockData = res.data;
|
||
state.value.lockData.orderId = state.value.orderId;
|
||
GetOrderById();
|
||
getLockerExpense();
|
||
}
|
||
});
|
||
};
|
||
const getLockerExpense = () => {
|
||
uni.showLoading({
|
||
mask: true,
|
||
});
|
||
getOrderApi
|
||
.ContinuationOrderPricePost({
|
||
orderId: state.value.orderId,
|
||
month: state.value.month,
|
||
couponIds: state.value.couponItem.map((item) => item.couponDispositionId),
|
||
point:state.value.point,
|
||
serialNumber: state.value.couponOtherItem.map(x => {
|
||
return {
|
||
dealGroupId: x.dealGroupId,
|
||
number: x.number,
|
||
marketPrice: x.marketPrice,
|
||
purchasePrice: x.price
|
||
}
|
||
})
|
||
})
|
||
.then((res) => {
|
||
uni.hideLoading();
|
||
if (res.code === 200) {
|
||
state.value.priceData = res.data;
|
||
}
|
||
if(res.code === 1002){
|
||
uni.showModal({
|
||
title: t('common.title'),
|
||
content: t('common.ORDER_AMOUNT_ERROR'),
|
||
showCancel: false,
|
||
success: function () {
|
||
clearCoupon();
|
||
state.value.point = 0;
|
||
},
|
||
});
|
||
}
|
||
});
|
||
};
|
||
const next = async () => {
|
||
uni.showLoading({
|
||
mask: true,
|
||
});
|
||
// if (!state.value.checked) {
|
||
// uni.showToast({
|
||
// title: t("detail.agreeTip"),
|
||
// icon: "none",
|
||
// duration: 2000
|
||
// });
|
||
// return;
|
||
// }
|
||
// 微信就判断 用户是否有手机号 H5就直接下单
|
||
// #ifdef MP-WEIXIN
|
||
const res = await getUserInfo();
|
||
if (res.code === 200) {
|
||
if (!res.data.phone) {
|
||
uni.hideLoading();
|
||
popup.value.open();
|
||
return;
|
||
}
|
||
}
|
||
getOrderApi
|
||
.ContinuationOrder({
|
||
orderId: state.value.orderId,
|
||
month: state.value.month,
|
||
couponIds: state.value.couponItem.map((item) => item.couponDispositionId),
|
||
point:state.value.point,
|
||
serialNumber: state.value.couponOtherItem.map(x => {
|
||
return {
|
||
dealGroupId: x.dealGroupId,
|
||
number: x.number,
|
||
marketPrice: x.marketPrice,
|
||
purchasePrice: x.price
|
||
}
|
||
})
|
||
})
|
||
.then((res) => {
|
||
uni.hideLoading();
|
||
if (res.code === 200) {
|
||
uni.requestPayment({
|
||
provider: "wxpay",
|
||
timeStamp: res.data.timeStamp, // 从服务器获取的时间戳
|
||
nonceStr: res.data.nonceStr, // 从服务器获取的随机字符串
|
||
package: `prepay_id=${res.data.package}`, // 从服务器获取的预支付交易会话标识
|
||
signType: res.data.signType, // 签名方式
|
||
paySign: res.data.paySign, // 从服务器获取的签名
|
||
success(res) {
|
||
// 支付成功
|
||
state.value.paySuccessOrfail = true;
|
||
state.value.showPayAfterMoadl = true;
|
||
console.log("支付成功", res);
|
||
},
|
||
fail(err) {
|
||
// 关闭订单
|
||
getOrderApi.CloseWeChatPayment({out_trade_no:res.data.nonceStr});
|
||
// 支付失败
|
||
state.value.paySuccessOrfail = false;
|
||
state.value.showPayAfterMoadl = true;
|
||
console.error("支付失败", err);
|
||
},
|
||
});
|
||
}
|
||
if(res.code === 1002){
|
||
uni.showModal({
|
||
title: t('common.title'),
|
||
content: t('common.ORDER_AMOUNT_ERROR'),
|
||
showCancel: false,
|
||
success: function () {
|
||
clearCoupon();
|
||
state.value.point = 0;
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// #endif
|
||
// #ifndef MP-WEIXIN
|
||
// let startTime = data.toISOString()
|
||
uni.showLoading();
|
||
getOrderApi
|
||
.ContinuationOrderH5({
|
||
orderId: state.value.orderId,
|
||
month: state.value.month,
|
||
couponIds: state.value.couponItem.map((item) => item.couponDispositionId),
|
||
})
|
||
.then((res) => {
|
||
uni.hideLoading();
|
||
if (res.code === 200) {
|
||
// 支付成功
|
||
state.value.paySuccessOrfail = true;
|
||
state.value.showPayAfterMoadl = true;
|
||
} else {
|
||
// 支付失败
|
||
state.value.paySuccessOrfail = false;
|
||
state.value.showPayAfterMoadl = true;
|
||
}
|
||
});
|
||
// #endif
|
||
};
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
@import "@/static/style/theme.scss";
|
||
.order-wrap {
|
||
background: linear-gradient(0deg, var(--left-linear), var(--right-linear));
|
||
}
|
||
|
||
.container {
|
||
padding: 0 30rpx 40rpx;
|
||
font-size: 14px;
|
||
line-height: 24px;
|
||
|
||
.payAfter {
|
||
width: 100%;
|
||
display: flex;
|
||
justify-content: center;
|
||
flex-wrap: wrap;
|
||
.payAfterIcon {
|
||
width: 100%;
|
||
display: flex;
|
||
justify-content: center;
|
||
padding: 20px;
|
||
}
|
||
.payAfterText {
|
||
font-size: 28rpx;
|
||
}
|
||
}
|
||
|
||
.agreed {
|
||
display: flex;
|
||
margin: 0 20rpx 20rpx;
|
||
font-weight: bold;
|
||
|
||
.check-wrap {
|
||
min-width: 40rpx;
|
||
height: 40rpx;
|
||
border: 6rpx solid #242a37;
|
||
border-radius: 50%;
|
||
margin: 4rpx 20rpx 0 0;
|
||
&.checked {
|
||
background-color: var(--active-color);
|
||
}
|
||
}
|
||
.read {
|
||
color: #323233;
|
||
}
|
||
.stress {
|
||
color: var(--active-color);
|
||
}
|
||
}
|
||
|
||
.box3 {
|
||
position: relative;
|
||
margin-top: 20rpx;
|
||
padding: 20rpx;
|
||
background-color: rgba(255, 255, 255, 0.95);
|
||
border-radius: 18rpx;
|
||
.bth {
|
||
padding: 0 20rpx;
|
||
margin: 40rpx 0;
|
||
button {
|
||
padding: 4px 0;
|
||
font-size: 28rpx;
|
||
font-weight: bold;
|
||
color: var(--text-color);
|
||
background: var(--active-color);
|
||
border-radius: 16rpx;
|
||
}
|
||
}
|
||
.tips {
|
||
color: #2a3447;
|
||
font-size: 22rpx;
|
||
font-weight: bold;
|
||
}
|
||
.fee {
|
||
margin: 10rpx 0;
|
||
.info {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
font-size: 28rpx;
|
||
color: #242a37;
|
||
font-weight: bold;
|
||
.left {
|
||
display: flex;
|
||
align-items: center;
|
||
&::before {
|
||
content: " ";
|
||
display: block;
|
||
background: var(--main-color);
|
||
height: 24rpx;
|
||
width: 6rpx;
|
||
border-radius: 4rpx;
|
||
margin-right: 10rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.monthSelect {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
justify-content: space-between;
|
||
.month {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-sizing: border-box;
|
||
margin-bottom: 10rpx;
|
||
width: 49%;
|
||
font-size: 22rpx;
|
||
background-color: #f2f0e9;
|
||
border: 1px solid #242e42;
|
||
padding: 4rpx 8rpx;
|
||
font-weight: bold;
|
||
border-radius: 8rpx;
|
||
image {
|
||
width: 21rpx;
|
||
height: 28rpx;
|
||
margin-left: 4rpx;
|
||
}
|
||
&.active {
|
||
background-color: var(--active-color);
|
||
}
|
||
}
|
||
}
|
||
.select {
|
||
font-size: 28rpx;
|
||
border-bottom: 1px dashed #d8d8d857;
|
||
.label {
|
||
font-weight: bold;
|
||
margin-top: 10rpx;
|
||
color: #b5b4b4;
|
||
}
|
||
.info {
|
||
color: #323233;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
font-weight: bold;
|
||
padding: 0 18rpx;
|
||
opacity: 0.7;
|
||
&.Total {
|
||
margin-top: 10rpx;
|
||
color: #242e42;
|
||
opacity: 1;
|
||
}
|
||
}
|
||
.garyBox {
|
||
background-color: rgba(216, 216, 216, 0.3);
|
||
border-radius: 8rpx;
|
||
padding: 2rpx 10rpx;
|
||
font-size: 20rpx;
|
||
font-weight: bold;
|
||
color: rgb(36, 46, 66);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin: 10rpx 4rpx;
|
||
}
|
||
.inputBox {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 16rpx 20rpx;
|
||
.value {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
color: #242e42;
|
||
font-size: 28rpx;
|
||
font-weight: bold;
|
||
}
|
||
.arrow {
|
||
display:flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
// width: 80rpx;
|
||
button {
|
||
height: 54rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 4rpx 20rpx;
|
||
font-size: 28rpx;
|
||
font-weight: bold;
|
||
color: var(--text-color);
|
||
background: var(--active-color);
|
||
border-radius: 16rpx;
|
||
}
|
||
}
|
||
image {
|
||
width: 20rpx;
|
||
height: 12rpx;
|
||
}
|
||
}
|
||
}
|
||
&::after {
|
||
content: "";
|
||
position: absolute;
|
||
bottom: -7px;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 14px;
|
||
background: radial-gradient( var(--left-linear) 0px, var(--left-linear) 5px, transparent 5px, transparent);
|
||
background-size: 14px 14px;
|
||
z-index: 9;
|
||
}
|
||
}
|
||
.box2 {
|
||
margin-top: 20rpx;
|
||
display: flex;
|
||
background: rgba(255, 255, 255, 0.95);
|
||
border-radius: 18rpx;
|
||
padding: 20rpx;
|
||
.left {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-between;
|
||
font-size: 28rpx;
|
||
font-weight: bold;
|
||
.left1 {
|
||
padding: 10rpx 0;
|
||
}
|
||
.left2 {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 10rpx 0;
|
||
&::before {
|
||
content: " ";
|
||
display: block;
|
||
width: 22rpx;
|
||
height: 22rpx;
|
||
background-color: #212938;
|
||
margin-right: 20rpx;
|
||
}
|
||
}
|
||
}
|
||
.right {
|
||
.right-image {
|
||
width: 406rpx;
|
||
height: 342rpx;
|
||
}
|
||
}
|
||
}
|
||
.topBox {
|
||
border-radius: 32rpx;
|
||
|
||
.pirce {
|
||
position: relative;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
padding: 70rpx 7% 20rpx;
|
||
margin-top: -30rpx;
|
||
color: #242a37;
|
||
font-size: 44rpx;
|
||
font-weight: bold;
|
||
background: #FFFFFF;
|
||
opacity: 0.95;
|
||
border-radius: 16rpx;
|
||
|
||
.left {
|
||
position: relative;
|
||
&:after {
|
||
content: " ";
|
||
display: block;
|
||
width: 120%;
|
||
height: 2px;
|
||
background-color: var(--btn-color3);
|
||
transform: rotate(9deg);
|
||
position: absolute;
|
||
top: 50%;
|
||
left: -5px;
|
||
}
|
||
}
|
||
|
||
&::after {
|
||
content: "";
|
||
position: absolute;
|
||
bottom: -7px;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 14px;
|
||
background: radial-gradient( var(--right-linear) 0px, var(--right-linear) 5px, transparent 5px, transparent);
|
||
background-size: 14px 14px;
|
||
z-index: 9;
|
||
}
|
||
}
|
||
|
||
.info {
|
||
background: linear-gradient(180deg, var(--bg-color), var(--bg-color2));
|
||
position: relative;
|
||
border-radius: 20rpx;
|
||
padding: 40rpx;
|
||
color: #ffffff;
|
||
display: flex;
|
||
align-items: center;
|
||
line-height: 1.4;
|
||
font-weight: bold;
|
||
z-index: 1;
|
||
|
||
.info-left {
|
||
padding: 0 40rpx;
|
||
font-size: 80rpx;
|
||
line-height: 1;
|
||
word-break: break-all;
|
||
}
|
||
|
||
.info-right {
|
||
flex: 1;
|
||
font-size: 24rpx;
|
||
}
|
||
|
||
&::before {
|
||
content: "";
|
||
position: absolute;
|
||
top: -7px;
|
||
left: 4px;
|
||
width: 100%;
|
||
height: 14px;
|
||
background: radial-gradient(var(--right-linear) 0px, var(--right-linear) 5px, transparent 5px, transparent);
|
||
background-size: 14px 14px;
|
||
z-index: 9;
|
||
}
|
||
|
||
// .span {
|
||
// position: absolute;
|
||
// inset: 0;
|
||
// rotate: 180deg;
|
||
// border-radius: 18rpx;
|
||
// &::before{
|
||
// content: "";
|
||
// position: absolute;
|
||
// bottom: 0;
|
||
// width: 100%;
|
||
// background-repeat: repeat;
|
||
// height: 4.5px;
|
||
// background-image: radial-gradient(
|
||
// circle at 2.5px 3.75px,
|
||
// #0a84b8 3px,
|
||
// transparent 3.5px
|
||
// );
|
||
// background-size: 10px 5px;
|
||
// /* 让波浪边框不会执行动画 */
|
||
|
||
// }
|
||
// &::after {
|
||
// content: "";
|
||
// position: absolute;
|
||
// bottom: 0;
|
||
// width: 100%;
|
||
// background-repeat: repeat;
|
||
// height: 0px;
|
||
// background-image: radial-gradient(
|
||
// circle at 2.5px -1.45px,
|
||
// transparent 6px,
|
||
// #0a84b8 3.75px
|
||
// );
|
||
// background-size: 5px 5px;
|
||
// }
|
||
// }
|
||
}
|
||
}
|
||
}
|
||
</style>
|