1771 lines
51 KiB
Vue
1771 lines
51 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.size") }}:{{ state.lockData.volume }} m³</view
|
||
>
|
||
<view class="text"
|
||
>{{ $t("detail.spec") }}:{{ removeTrailingZeros(state.lockData.length) }}m *
|
||
{{ removeTrailingZeros(state.lockData.width) }}m * {{ removeTrailingZeros(state.lockData.height) }}m</view
|
||
>
|
||
</view>
|
||
</view>
|
||
<view class="pirce">
|
||
<view class="left" v-if="!state.lockData.isFlashSale || state.isShortTerm"> {{ currency }} {{ state.lockData.price }} </view>
|
||
<view class="left left-flash" v-else> {{ currency }} {{ state.lockData.flashSalePrice }} </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" @click="showCalendar">
|
||
<view class="value">
|
||
{{ dayjs(state.startDate).format("YYYY/MM/DD") }}
|
||
</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="select">
|
||
<view class="label"> * {{ $t("detail.lease") }} </view>
|
||
<view class="inputBox" @click="showMonthPicker">
|
||
<view class="value" v-if="!state.isShortTerm">
|
||
{{ $t("months",{count: state.month}) }}
|
||
</view>
|
||
<view class="value" v-else>
|
||
{{ state.lockData.shortTermDay }} {{ $t("common.day") }}
|
||
</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 class="month" @click="SelectShortTerm()" :class="'短租' == selectMonthIndex ? 'active' : ''" v-if="state.lockData.isShortTerm">
|
||
{{ state.lockData.shortTermDay }} {{ $t("common.day") }}
|
||
</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.stop.prevent="openCoupon" v-if="!state.isShortTerm">
|
||
<view class="label"> * {{ $t("detail.coupon") }} </view>
|
||
<view class="inputBox">
|
||
<view class="value">
|
||
<template v-if="state.couponOtherItem.length">
|
||
<view v-for="(item, index) in state.couponOtherItem" :key="index">
|
||
<!-- {{ item.platform }} {{ item.marketPrice }} -->
|
||
{{ item.title }}
|
||
</view>
|
||
<!-- <template v-if="!state.couponItem.length &&!state.couponOtherItem.length">,</template> -->
|
||
</template>
|
||
<view v-for="(item, index) in state.couponItem" :key="index"
|
||
>{{ item.couponCode }}
|
||
{{
|
||
couponDesc(item)
|
||
}}
|
||
</view
|
||
>
|
||
<template v-if="!state.couponItem.length &&!state.couponOtherItem.length">{{
|
||
$t("detail.noselect")
|
||
}}</template>
|
||
<!-- {{$t("detail.noselect") }} -->
|
||
</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" 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">
|
||
<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="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.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>
|
||
<!-- #ifdef MP-WEIXIN -->
|
||
<view class="bth">
|
||
<button class="next-btn" @click="next(false)">
|
||
{{ $t("detail.next") }}
|
||
</button>
|
||
</view>
|
||
<view class="bth quotation" v-if="storeState.userInfo?.userType == 2">
|
||
<template v-if="quotationData.path">
|
||
<button class="recreate" @click="generateQuotation">
|
||
{{ $t("detail.regenerateQuotation") }}
|
||
</button>
|
||
<button class="view" @click="openQuotation">
|
||
{{ $t("detail.viewQuotation") }}
|
||
</button>
|
||
</template>
|
||
<button class="create" @click="generateQuotation" v-else>
|
||
{{ $t("detail.generateQuotation") }}
|
||
</button>
|
||
</view>
|
||
|
||
<!-- #endif -->
|
||
|
||
<!-- #ifdef H5 -->
|
||
<view class="bth">
|
||
<button class="next-btn" @click="next(false)">
|
||
{{ $t("detail.next") }}
|
||
</button>
|
||
</view>
|
||
<!-- #endif -->
|
||
|
||
<!-- #ifdef MP-XHS -->
|
||
<view class="bth">
|
||
<button class="next-btn" @click="makePhoneCall">
|
||
{{ $t("home.serviceHotline") }} {{ projectInfo.phone }}
|
||
</button>
|
||
</view>
|
||
<!-- #endif -->
|
||
|
||
<!-- #ifdef MP-WEIXIN || H5 -->
|
||
<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="openAgreement">{{
|
||
$t("detail.agreement")
|
||
}}</text>
|
||
</view>
|
||
<!-- <checkbox class="myCheckbox" @click="changeCheck" :checked="state.checked"> </checkbox> -->
|
||
</view>
|
||
<!-- #endif -->
|
||
</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"
|
||
:date = "state.startDate"
|
||
confirmText="Confirm"
|
||
cancelText="Cancel"
|
||
:color="themeInfo.activeColor"
|
||
:end-date="state.maxDate"
|
||
@confirm="calendarConfirm"
|
||
/>
|
||
|
||
<uv-popup
|
||
ref="popup"
|
||
customStyle="width: 80%;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>
|
||
<!-- <uv-form labelPosition="left" labelWidth="auto" ref="formRef">
|
||
<uv-form-item :label="$t('common.userName')" prop="username">
|
||
<uv-input v-model="state.username" class="weui-input"
|
||
:placeholder="$t('common.userName')" />
|
||
</uv-form-item>
|
||
</uv-form> -->
|
||
<!-- #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>
|
||
<template #affterBtn>
|
||
<view v-if="state.paySuccessOrfail" class="modal-button-1" @click="goAControl">{{ $t("unlock.FaceEnrollment") }}</view>
|
||
</template>
|
||
</myModal>
|
||
<!-- 是否去验证个人信息 -->
|
||
<myModal
|
||
v-model="state.showIsGoAuth"
|
||
:content="$t('common.isGoAuth')"
|
||
:confirmText="$t('common.Authentication')"
|
||
@confirm="goAuth"
|
||
></myModal>
|
||
<!-- 提醒用户 需要验证 -->
|
||
<myModal
|
||
v-model="state.shouldGotoAuth"
|
||
:content="$t('common.AuthenticationFailedTips')"
|
||
:confirmText="$t('common.addOrder')"
|
||
@confirm="next(true)"
|
||
>
|
||
|
||
<view @click="goAuth" style="text-decoration: underline;color: blue;">
|
||
{{ $t('common.Authentication') }}
|
||
</view>
|
||
|
||
</myModal>
|
||
<!-- 优惠卷 -->
|
||
<coupon
|
||
ref="couponRef"
|
||
:siteData="state.lockData"
|
||
:couponOtherItem="state.couponOtherItem"
|
||
:couponItem="state.couponItem"
|
||
:priceData="state.priceData"
|
||
:month="state.month"
|
||
v-model="state.couponShow"
|
||
@chooseCoupon="chooseCoupon"
|
||
@chooseOtherCoupon = "chooseOtherCoupon"
|
||
@confirm="confirmCoupon"
|
||
:disabledFunc="disabledFunc"
|
||
></coupon>
|
||
<updatePopup ref="updatePopupRef" :name="state.lockData.siteName"></updatePopup>
|
||
|
||
<!-- 是否确认所绑的中介 -->
|
||
<myModal v-model="state.confirmReferrer" :content="$t('order.confirmReferrer', { referrer: state.referrerInfo.mediatorName })" @confirm="resolvePromise(true)" @close="resolvePromise(false)"></myModal>
|
||
|
||
<uv-popup ref="agreementRef" mode="bottom" :closeOnClickOverlay="false" width="750rpx" round="20">
|
||
<view class="agreement-wrap">
|
||
<view class="agreement-top">
|
||
<view class="name">{{ $t("detail.agreement") }}</view>
|
||
<uv-icon name="close" size="20" @click="closeAgreement"></uv-icon>
|
||
</view>
|
||
<scroll-view class="agreement-content" :scroll-top="state.scrollTop" scroll-y="true"
|
||
@scrolltolower="handleScrollBottom" @scroll="handleScroll">
|
||
<!-- themeInfo.language === 'en_lang' ? state.enAgreementContent : state.agreementContent -->
|
||
<uv-parse :content="state.agreementContent"></uv-parse>
|
||
<view style="margin-top: 200rpx;">
|
||
<uv-loading-icon v-if="!state.agreementContent" :vertical="true" :text="$t('common.loading')"></uv-loading-icon>
|
||
</view>
|
||
</scroll-view>
|
||
<view class="roll-btn" @click="handleRoll">
|
||
<uv-icon name="arrow-down" size="24" color="#FFFFFF"></uv-icon>
|
||
</view>
|
||
<view class="bottom-read agree" v-if="state.isRead" @click="handleAgree">{{ $t("detail.agreeTerm") }}</view>
|
||
<view class="bottom-read" v-else>{{ $t("detail.scrollRead") }}</view>
|
||
</view>
|
||
</uv-popup>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { reactive, ref, watch, watchEffect } from "vue";
|
||
import navBar from "@/components/navBar.vue";
|
||
import { onLoad, onShow, onShareAppMessage } from "@dcloudio/uni-app";
|
||
import { useSiteApi } from "@/Apis/site.js";
|
||
import { useOrderApi } from "@/Apis/order.js";
|
||
import { useLoginApi } from "@/Apis/login.js";
|
||
import { authInfoApi } from "@/Apis/validInfo.js";
|
||
import { navigateBack, removeTrailingZeros, makePhoneCall } from "@/utils/common.js";
|
||
import coupon from "@/components/coupon.vue";
|
||
import updatePopup from "@/components/updatePopup.vue";
|
||
import dayjs from "dayjs";
|
||
import { baseImageUrl, projectInfo,setOrderDays,currency } from "@/config/index.js";
|
||
// 主题色配置
|
||
import { useMainStore } from "@/store/index.js";
|
||
import myModal from "@/components/myModal.vue";
|
||
import { useI18n } from "vue-i18n";
|
||
import { isKingKong } from "../../config";
|
||
import { getClientCustomerApi } from "@/Apis/clientCustomer.js";
|
||
const clientCustomerApi = getClientCustomerApi();
|
||
const { themeInfo, getUserInfo, storeState } = useMainStore();
|
||
const { t } = useI18n();
|
||
const agreementRef = ref();
|
||
const picker = ref();
|
||
const calendars = ref();
|
||
const getApi = useSiteApi();
|
||
const getLoginApi = useLoginApi();
|
||
const getOrderApi = useOrderApi();
|
||
const getAuthApi = authInfoApi();
|
||
const checked = ref(true);
|
||
const couponRef = ref();
|
||
const popup = ref();
|
||
const updatePopupRef = ref();
|
||
const columns = [];
|
||
columns[0] = Array.from({ length: 36 }, (v, i) => ({
|
||
label: t(`month${i + 1 > 1 ? "s" : ""}`, { count: i + 1 }),
|
||
id: i + 1,
|
||
}));
|
||
const showImage = (url) => {
|
||
uni.previewImage({
|
||
urls: [url],
|
||
});
|
||
};
|
||
|
||
const today = dayjs()
|
||
.set("hour", 0)
|
||
.set("minute", 0)
|
||
.set("second", 0)
|
||
.set("millisecond", 0);
|
||
// 生成当天一个月后的日期
|
||
let oneMonthLater = today.add(setOrderDays, "day");
|
||
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;
|
||
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;
|
||
const canAdd = canAddValue(state.value.couponItem.map(x=>x.couponType),item.couponType)
|
||
return !(isSite && isUnit && isPrice && isDate&& canAdd);
|
||
};
|
||
// 根据优惠卷类型 返回优惠卷 作用范围 优惠多少钱 打多少折 首页多少钱
|
||
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}`
|
||
}
|
||
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 chooseCoupon = (item) => {
|
||
// 可以叠加就添加
|
||
if(item.couponType == 5){
|
||
if(state.value.month<item.fullMonth){
|
||
uni.showToast({
|
||
title: `月数不足${item.fullMonth}个月,无法此优惠卷!`,
|
||
icon: "none",
|
||
duration: 2000,
|
||
});
|
||
return
|
||
}
|
||
}
|
||
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 chooseOtherCoupon= (item) => {
|
||
const isE = state.value.couponOtherItem.find(x=>x.number == item.number);
|
||
if (!isE) {
|
||
state.value.couponOtherItem.push(item);
|
||
}
|
||
getLockerExpense();
|
||
}
|
||
const state = ref({
|
||
checked: false,
|
||
lockerId: "",
|
||
startDate: today.format("YYYY/MM/DD"),
|
||
minDate: today.format("YYYY/MM/DD"),
|
||
maxDate: oneMonthLater.format("YYYY/MM/DD"),
|
||
month: 24,
|
||
lockData: {},
|
||
priceData: {},
|
||
tempFilePath: "",
|
||
showPayAfterMoadl: false, //打开支付窗口
|
||
paySuccessOrfail: false, // 支付状态
|
||
couponShow: false, // 优惠卷窗口
|
||
showIsGoAuth: false, // 是否去验证个人信息
|
||
shouldGotoAuth: false, // 提示验证个人信息,但不是必須
|
||
couponItem: [], // 优惠卷
|
||
couponOtherItem:[],
|
||
orderId: "",
|
||
username: "",
|
||
checkAgreementUrlTime:0,
|
||
zhuangxiuzhong: false,
|
||
isShortTerm: false,
|
||
confirmReferrer: false, // 是否确认绑定的中介
|
||
referrerInfo: {
|
||
id: ''
|
||
}, // 中介信息
|
||
checkAgreementUrlTime:0,
|
||
agreementContent: "无",
|
||
enAgreementContent: "无",
|
||
scrollTop: 0,
|
||
oldScrollTop: 0,
|
||
isRead: false,
|
||
point: 0,
|
||
});
|
||
|
||
let resolvePromise = ref(null);
|
||
|
||
const resolveConfirmReferrer = () => {
|
||
return new Promise((resolve) => {
|
||
resolvePromise.value = resolve;
|
||
});
|
||
}
|
||
|
||
|
||
const GetLockerAgreementHTMLById = () => {
|
||
getApi.GetLockerAgreementHTMLById({lockerId: state.value.lockerId}).then((res) => {
|
||
if (res.code === 200) {
|
||
state.value.agreementContent = res.data;
|
||
}
|
||
});
|
||
};
|
||
// 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 都可以
|
||
}
|
||
|
||
// const pointsChange = () => {
|
||
// getLockerExpense();
|
||
// }
|
||
const handleRoll = () => {
|
||
state.value.oldScrollTop += 4000;
|
||
state.value.scrollTop = state.value.oldScrollTop;
|
||
}
|
||
|
||
// 滑动到底部了
|
||
const handleScrollBottom = () => {
|
||
state.value.isRead = true;
|
||
}
|
||
|
||
const handleScroll = (e) => {
|
||
state.value.oldScrollTop = e.detail.scrollTop;
|
||
}
|
||
|
||
const handleAgree = () => {
|
||
state.value.checked = true;
|
||
closeAgreement();
|
||
}
|
||
|
||
const openAgreement = () => {
|
||
state.value.scrollTop = state.value.oldScrollTop;
|
||
agreementRef?.value.open();
|
||
};
|
||
|
||
const closeAgreement = () => {
|
||
agreementRef?.value.close();
|
||
};
|
||
|
||
|
||
const GetStartDateRntalByKey = () => {
|
||
getOrderApi.GetStartDateRntalByKey({ lockerId: state.value.lockerId }).then(res=>{
|
||
if(res.code === 200) {
|
||
state.value.maxDate = today.add(res.data.day, "day").format("YYYY/MM/DD")
|
||
if(state.value.zhuangxiuzhong) {
|
||
const limitDate = dayjs(state.value.lockData.preSaleTime).format("YYYY/MM/DD");
|
||
// 订单可以租用
|
||
if (today.isBefore(limitDate)) {
|
||
if(dayjs(state.value.startDate, "YYYY/MM/DD").isBefore(limitDate)) {
|
||
state.value.startDate = limitDate;
|
||
}
|
||
state.value.minDate = limitDate;
|
||
}
|
||
}
|
||
} else {
|
||
uni.showToast({
|
||
title: "获取数据失败",
|
||
icon: "none",
|
||
duration: 2000,
|
||
});
|
||
}
|
||
})
|
||
};
|
||
const openCoupon = () => {
|
||
couponRef.value.open();
|
||
};
|
||
const goAControl = () => {
|
||
if(state.value.orderId){
|
||
uni.reLaunch({
|
||
url: "/pagesb/AControl/index?id=" + state.value.orderId,
|
||
});
|
||
}else{
|
||
payAfterconfirm()
|
||
}
|
||
|
||
};
|
||
const payAfterconfirm = () => {
|
||
// if (state.value.paySuccessOrfail) { }
|
||
uni.reLaunch({
|
||
url: "/pages/unlock/index",
|
||
});
|
||
|
||
};
|
||
|
||
const confirmCoupon = (data)=>{
|
||
const { couponItem, couponOtherItem } = data;
|
||
state.value.couponItem = couponItem;
|
||
state.value.couponOtherItem = couponOtherItem;
|
||
getLockerExpense();
|
||
couponRef.value.close();
|
||
}
|
||
|
||
const clearCoupon = () => {
|
||
state.value.couponItem = [];
|
||
state.value.couponOtherItem = [];
|
||
state.value.point = 0;
|
||
getLockerExpense();
|
||
};
|
||
|
||
const openFile = () => {
|
||
state.value.checkAgreementUrlTime++;
|
||
if (state.value.lockData.agreementUrl) {
|
||
// #ifdef MP-WEIXIN
|
||
// 下载 打开文件
|
||
if (state.value.tempFilePath) {
|
||
openDocument();
|
||
return;
|
||
}
|
||
uni.showLoading();
|
||
uni.downloadFile({
|
||
url: baseImageUrl + state.value.lockData.agreementUrl,
|
||
success: (res) => {
|
||
if (res.statusCode === 200) {
|
||
state.value.tempFilePath = res.tempFilePath;
|
||
openDocument();
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.log(err);
|
||
},
|
||
complete: () => {
|
||
uni.hideLoading();
|
||
},
|
||
});
|
||
// #endif
|
||
// #ifdef H5
|
||
uni.navigateTo({
|
||
url:
|
||
"/pages/webview/web?url=" +
|
||
encodeURIComponent(state.value.lockData.agreementUrl),
|
||
});
|
||
// #endif
|
||
} else {
|
||
uni.showToast({
|
||
title: "暂无协议",
|
||
icon: "none",
|
||
});
|
||
}
|
||
};
|
||
const openDocument = () => {
|
||
uni.openDocument({
|
||
filePath: state.value.tempFilePath,
|
||
success: function (res) {
|
||
console.log("打开文档成功");
|
||
},
|
||
});
|
||
};
|
||
const showMonthPicker = () => {
|
||
picker.value.open();
|
||
};
|
||
const showCalendar = () => {
|
||
calendars.value.open();
|
||
};
|
||
const changeCheck = () => {
|
||
if(state.value.checkAgreementUrlTime == 0){
|
||
uni.showToast({
|
||
title: t("common.checkAgreementUrl"),
|
||
icon: "none",
|
||
duration: 2000,
|
||
})
|
||
openAgreement();
|
||
return
|
||
}
|
||
state.value.checked = !state.value.checked;
|
||
};
|
||
const calendarConfirm = (e) => {
|
||
const fullDate = dayjs(e.fulldate); // 保持 dayjs 对象
|
||
|
||
if (state.value.zhuangxiuzhong) {
|
||
const limitDate = dayjs(state.value.lockData.preSaleTime);
|
||
|
||
if (fullDate.isBefore(limitDate)) {
|
||
uni.showModal({
|
||
title: t("common.title"),
|
||
content: t("storeRenovationNotice", {
|
||
limitDate: limitDate.format("YYYY/MM/DD")
|
||
}),
|
||
showCancel: false,
|
||
});
|
||
return;
|
||
} else {
|
||
state.value.startDate = fullDate.format("YYYY/MM/DD");
|
||
}
|
||
} else {
|
||
state.value.startDate = fullDate.format("YYYY/MM/DD");
|
||
}
|
||
};
|
||
const onMonthConfirm = (e) => {
|
||
state.value.month = e.value[0].id;
|
||
closeShortTerm();
|
||
clearCoupon();
|
||
};
|
||
const selectMonthIndex = ref(0);
|
||
const monthChange = (num, index) => {
|
||
state.value.month = num;
|
||
selectMonthIndex.value = index;
|
||
closeShortTerm();
|
||
clearCoupon();
|
||
};
|
||
|
||
const SelectShortTerm = () => {
|
||
state.value.isShortTerm = true;
|
||
selectMonthIndex.value = "短租";
|
||
clearCoupon();
|
||
}
|
||
const closeShortTerm = () => {
|
||
state.value.isShortTerm = false;
|
||
}
|
||
|
||
watchEffect(() => {
|
||
let discountList = state.value.lockData.discountList;
|
||
if (!discountList?.length) return;
|
||
let firstIndex = discountList.findIndex(
|
||
(item) => state.value.month >= item.month
|
||
);
|
||
selectMonthIndex.value = firstIndex;
|
||
if(state.value.isShortTerm){
|
||
selectMonthIndex.value = "短租";
|
||
}
|
||
});
|
||
|
||
// 如果当前最多使用积分 大于所选的置零
|
||
watch(()=>state.value.priceData?.maxPoint,()=>{
|
||
if(state.value.priceData?.maxPoint>state.value.point){
|
||
state.value.point = 0
|
||
getLockerExpense();
|
||
}
|
||
})
|
||
|
||
onLoad((params) => {
|
||
state.value.lockerId = params.id;
|
||
state.value.month = params?.month || 24;
|
||
if (params.q) {
|
||
const parseUrlRes = parseUrlParams(decodeURIComponent(params.q));
|
||
state.value.lockerId = parseUrlRes.id;
|
||
state.value.month = parseUrlRes.month || 24;
|
||
if(parseUrlRes.isShortTerm){
|
||
state.value.isShortTerm = true;
|
||
selectMonthIndex.value = "短租";
|
||
}
|
||
}
|
||
GetStartDateRntalByKey();
|
||
GetLockerAgreementHTMLById();
|
||
// 小红书onshow第一次 不会触发
|
||
// #ifdef MP-XHS
|
||
getLockerById();
|
||
// #endif
|
||
});
|
||
|
||
const getMediatorByUser = async () => {
|
||
const res = await clientCustomerApi.GetMediatorByUser();
|
||
if (res.code === 200 && res.data) {
|
||
state.value.referrerInfo = res.data;
|
||
}
|
||
};
|
||
|
||
const parseUrlParams = (url) => {
|
||
const params = {};
|
||
const queryString = url.split('?')[1];
|
||
if (!queryString) return params;
|
||
|
||
const pairs = queryString.split('&');
|
||
for (const pair of pairs) {
|
||
const [key, value] = pair.split('=');
|
||
if (key) {
|
||
params[decodeURIComponent(key)] = decodeURIComponent(value || '');
|
||
}
|
||
}
|
||
return params;
|
||
}
|
||
|
||
onShow(() => {
|
||
getLockerById();
|
||
});
|
||
onShareAppMessage((res) => {
|
||
return {
|
||
title: `${projectInfo.miniName}`,
|
||
path: `/pages/setOrder/index?id=${state.value.lockerId}&month=${state.value.month}&isShortTerm=${state.value.isShortTerm}`,
|
||
};
|
||
});
|
||
const phoneNumber = ref("");
|
||
function getPhoneNumber(e) {
|
||
uni.showLoading();
|
||
phoneNumber.value = e.detail.code;
|
||
if (e.detail.code) {
|
||
getLoginApi.GetPhoneNumber({code:e.detail.code,userName:state.value.username.trim()}).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 getLockerById = () => {
|
||
uni.showLoading();
|
||
getApi.GetLockerById({ lockerId: state.value.lockerId }).then((res) => {
|
||
if (res.code === 200) {
|
||
state.value.lockData = res.data;
|
||
if(state.value.lockData.isPreSale ) {
|
||
// 订单可以租用
|
||
state.value.zhuangxiuzhong = true;
|
||
const limitDate = dayjs(state.value.lockData.preSaleTime).format("YYYY/MM/DD");
|
||
if (today.isBefore(limitDate)) {
|
||
if(dayjs(state.value.startDate, "YYYY/MM/DD").isBefore(limitDate)) {
|
||
state.value.startDate = limitDate;
|
||
}
|
||
state.value.minDate = limitDate;
|
||
uni.showModal({
|
||
title: t("common.title"),
|
||
content: t("storeRenovationNotice",{limitDate}),
|
||
showCancel: false,
|
||
success: function () {},
|
||
});
|
||
}
|
||
}else{
|
||
state.value.zhuangxiuzhong = false;
|
||
}
|
||
// res.data == null 找不到订单 isPlaceOrder 等于订单不可以租用
|
||
if (!res.data || !res.data?.isPlaceOrder) {
|
||
// 支付回调 会触发onshow 这个会优先出来 所有 支付成功就不弹窗 会有一个支付成功的弹窗显示
|
||
if(!state.value.showPayAfterMoadl){
|
||
uni.showModal({
|
||
title: t("common.title"),
|
||
content: t("common.cantUselocker"),
|
||
showCancel: false,
|
||
success: function () {
|
||
if (res.data?.siteId) {
|
||
uni.reLaunch({
|
||
url: "/pages/site/index?id=" + res.data.siteId,
|
||
});
|
||
} else {
|
||
navigateBack();
|
||
}
|
||
},
|
||
});
|
||
}
|
||
|
||
uni.hideLoading();
|
||
return;
|
||
}
|
||
getLockerExpense();
|
||
} else {
|
||
if(!state.value.showPayAfterMoadl){
|
||
uni.showToast({
|
||
title: t("common.cantUselocker"),
|
||
icon: "none",
|
||
duration: 2000,
|
||
});
|
||
}
|
||
setTimeout(() => {
|
||
navigateBack();
|
||
}, 1000);
|
||
}
|
||
});
|
||
};
|
||
const getLockerExpense = () => {
|
||
uni.showLoading();
|
||
getApi
|
||
.GetLockerExpense({
|
||
lockerId: state.value.lockerId,
|
||
month: state.value.month,
|
||
couponIds: state.value.couponItem
|
||
.map((item) => item.couponDispositionId),
|
||
isShortTerm: state.value.isShortTerm,
|
||
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 goAuth = () => {
|
||
state.value.showIsGoAuth = false;
|
||
state.value.shouldGotoAuth = false;
|
||
uni.navigateTo({
|
||
url: "/pagesb/validationInfo/index",
|
||
});
|
||
};
|
||
const next = async (canAddOrder) => {
|
||
uni.showLoading({
|
||
mask: true,
|
||
});
|
||
let data = dayjs(state.value.startDate).format("YYYY-MM-DDTHH:mm:ssZ");
|
||
if (!state.value.checked) {
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: t("detail.agreeTip"),
|
||
icon: "none",
|
||
duration: 2000,
|
||
});
|
||
openAgreement();
|
||
return;
|
||
}
|
||
// 微信就判断 用户是否有手机号 H5就直接下单
|
||
// #ifdef MP-WEIXIN
|
||
// 判断是否登录
|
||
if (storeState && !storeState.token) {
|
||
uni.hideLoading();
|
||
updatePopupRef.value.open();
|
||
return;
|
||
}
|
||
const res = await getUserInfo();
|
||
if (res.code === 200) {
|
||
if (!res.data.phone) {
|
||
uni.hideLoading();
|
||
popup.value.open();
|
||
return;
|
||
}
|
||
}
|
||
// 如果是金刚 金刚可以跳过验证 但是时昌不可以
|
||
if(isKingKong){
|
||
if(!canAddOrder){
|
||
// 判断是否认证
|
||
let { code: verifyCode, data: verifyRes } =
|
||
await getAuthApi.GetIsCertification();
|
||
if (verifyCode == 200 && !verifyRes?.wasValid) {
|
||
uni.hideLoading();
|
||
state.value.showIsGoAuth = true;
|
||
return;
|
||
}
|
||
if( verifyCode == 200 && verifyRes.wasValid && !verifyRes?.isPass) {
|
||
uni.hideLoading();
|
||
state.value.shouldGotoAuth = true;
|
||
return
|
||
}
|
||
}
|
||
}else{
|
||
let { code: verifyCode, data: verifyRes } =
|
||
await getAuthApi.GetIsCertification();
|
||
|
||
if(verifyCode == 200 && !verifyRes?.isPass) {
|
||
uni.hideLoading();
|
||
state.value.showIsGoAuth = true;
|
||
return
|
||
}
|
||
}
|
||
// 获取是否存在中介信息
|
||
await getMediatorByUser();
|
||
// 确认中介信息
|
||
// let confirmReferrer = false;
|
||
// if (state.value.referrerInfo?.mediatorId) {
|
||
// uni.hideLoading();
|
||
// state.value.confirmReferrer = true;
|
||
// confirmReferrer = await resolveConfirmReferrer();
|
||
// }
|
||
getOrderApi
|
||
.AddOrder2({
|
||
lockerId: state.value.lockerId,
|
||
startTime: data,
|
||
month: state.value.month,
|
||
couponIds: state.value.couponItem.map((item) => item.couponDispositionId),
|
||
isShortTerm: state.value.isShortTerm,
|
||
mediatorId: state.value.referrerInfo?.mediatorId,
|
||
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.orderId = res.data.orderId;
|
||
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) {
|
||
uni.hideLoading();
|
||
// 关闭订单
|
||
// getOrderApi.CloseWeChatPayment({ out_trade_no: res.data.nonceStr });
|
||
// 支付失败
|
||
state.value.paySuccessOrfail = false;
|
||
state.value.showPayAfterMoadl = true;
|
||
console.error("支付失败", err);
|
||
},
|
||
});
|
||
} else {
|
||
if(res.code === 1001){
|
||
uni.showModal({
|
||
title: t('common.title'),
|
||
content: t('common.unpaidOrderTips'),
|
||
showCancel: false,
|
||
success: function () {
|
||
uni.switchTab({
|
||
url: '/pages/unlock/index',
|
||
})
|
||
},
|
||
})
|
||
return
|
||
}
|
||
}
|
||
});
|
||
// #endif
|
||
// #ifndef MP-WEIXIN
|
||
// let startTime = data.toISOString()
|
||
uni.showLoading();
|
||
getOrderApi
|
||
.AddOrder({
|
||
lockerId: state.value.lockerId,
|
||
startTime: data,
|
||
month: state.value.month,
|
||
couponIds: state.value.couponItem.map((item) => item.couponDispositionId),
|
||
isShortTerm: state.value.isShortTerm,
|
||
})
|
||
.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
|
||
};
|
||
// 报价单相关
|
||
const quotationData = reactive({
|
||
path: '',
|
||
loading: false,
|
||
});
|
||
|
||
const generateQuotation = async () => {
|
||
if (!state.value.lockerId || quotationData.loading) return;
|
||
quotationData.loading = true;
|
||
uni.showLoading();
|
||
let startTime = dayjs(state.value.startDate).format("YYYY-MM-DDTHH:mm:ssZ");
|
||
const arrayBuffer = await getOrderApi.GenerateQuotation({
|
||
lockerId: state.value.lockerId,
|
||
startTime,
|
||
month: state.value.month,
|
||
isShortTerm: state.value.isShortTerm,
|
||
});
|
||
if (!arrayBuffer) {
|
||
uni.showToast({
|
||
title: t('detail.quotationFail'),
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
};
|
||
try {
|
||
const name = `${state.value.lockData.siteName}_${state.value.lockData.name}_${state.value.month}个月报价单${new Date().getTime()}.pdf`;
|
||
const filePath = `${uni.env.USER_DATA_PATH}/${name}`;
|
||
const fileManager = uni.getFileSystemManager();
|
||
fileManager.writeFile({
|
||
filePath: filePath,
|
||
data: arrayBuffer,
|
||
encoding: 'binary',
|
||
success: () => {
|
||
uni.hideLoading();
|
||
quotationData.loading = false;
|
||
quotationData.path = filePath;
|
||
uni.showToast({
|
||
title: t('detail.quotationSuccess'),
|
||
icon: 'none',
|
||
duration: 1000
|
||
});
|
||
setTimeout(() => {
|
||
openQuotation();
|
||
}, 1000);
|
||
},
|
||
fail: (error) => {
|
||
quotationData.loading = false;
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: t('detail.quotationFail'),
|
||
icon: 'none'
|
||
});
|
||
console.log(error);
|
||
}
|
||
});
|
||
} catch (error) {
|
||
quotationData.loading = false;
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: t('detail.quotationFail'),
|
||
icon: 'none'
|
||
});
|
||
console.log('生成报价单失败', error);
|
||
}
|
||
}
|
||
|
||
const openQuotation = () => {
|
||
uni.openDocument({
|
||
filePath: quotationData.path,
|
||
showMenu: true,
|
||
fail: (error) => {
|
||
console.log(error);
|
||
}
|
||
});
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
@import "@/static/style/theme.scss";
|
||
.order-wrap {
|
||
background: linear-gradient(0deg, var(--left-linear), var(--right-linear));
|
||
.agreement-wrap {
|
||
position: relative;
|
||
height: 70vh;
|
||
padding: 20rpx 40rpx;
|
||
border-radius: 28rpx 28rpx 0 0;
|
||
background: #FFFFFF;
|
||
|
||
.agreement-top {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
padding: 20rpx 30rpx;
|
||
margin-bottom: 20rpx;
|
||
|
||
.name {
|
||
font-size: 32rpx;
|
||
}
|
||
}
|
||
|
||
.agreement-content {
|
||
height: calc(100% - 200rpx);
|
||
overflow: auto;
|
||
}
|
||
|
||
.roll-btn {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
position: absolute;
|
||
right: 40rpx;
|
||
bottom: 120rpx;
|
||
width: 80rpx;
|
||
height: 80rpx;
|
||
border-radius: 10rpx;
|
||
background: rgba(var(--rgb-color), 0.7);
|
||
}
|
||
|
||
.bottom-read {
|
||
width: 100%;
|
||
// margin: 30rpx 0;
|
||
padding: 20rpx 0;
|
||
color: var(--text-color);
|
||
border-radius: 10rpx;
|
||
text-align: center;
|
||
background: var(--left-linear);
|
||
opacity: 0.4;
|
||
|
||
&.agree {
|
||
opacity: 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
:deep(.modal-button-1) {
|
||
width: 260rpx;
|
||
height: 72rpx;
|
||
background: #F4F3F3;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 30rpx;
|
||
font-weight: 700;
|
||
border-radius: 14rpx;
|
||
margin-left: 20upx;
|
||
&:active {
|
||
background: #888;
|
||
}
|
||
}
|
||
|
||
.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;
|
||
}
|
||
&.quotation {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
.recreate {
|
||
width: 58%;
|
||
}
|
||
.view {
|
||
width: 38%;
|
||
}
|
||
.create {
|
||
width: 100%;
|
||
}
|
||
}
|
||
}
|
||
.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;
|
||
width: 50%;
|
||
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>
|