Feat: 订单流程
This commit is contained in:
@@ -0,0 +1,420 @@
|
||||
<template>
|
||||
<view class="submit-order">
|
||||
<scroll-view scroll-y class="page-scroll">
|
||||
<!-- 商品卡片 -->
|
||||
<view class="card">
|
||||
<view class="product-card">
|
||||
<image class="thumb" :src="orderInfo.travelGroupProduct.mainImage" mode="aspectFill" />
|
||||
<view class="info">
|
||||
<view class="title">{{ orderInfo.travelGroupProduct.name }}</view>
|
||||
<view class="price-row">
|
||||
<text class="label">实付:</text>
|
||||
<text class="price v12-primary-text"><text class="v12-font-20">¥</text>{{ orderInfo.priceGroup.totalPrice }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="notice v12-font-28 v12-primary-text">下单成功后记得联系商家确认入住时间哦~</view>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 填写信息 -->
|
||||
<view class="card form-card">
|
||||
<view class="section-title">填写您的信息</view>
|
||||
<view class="form-item">
|
||||
<text class="form-label">姓 名:</text>
|
||||
<u-input shape="circle" placeholderStyle="font-size: 24rpx;" v-model="form.name" placeholder="请填写姓名" border="surround" />
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="form-label">联系电话:</text>
|
||||
<u-input shape="circle" placeholderStyle="font-size: 24rpx;" v-model="form.phone" placeholder="请填写联系电话" border="surround" />
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="form-label">入住时间:</text>
|
||||
<view class="date-row" @click="chooseDate">
|
||||
<text class="date-val v12-primary-text">{{ dateRangeText }}</text>
|
||||
<!-- <u-icon name="arrow-right" size="18" color="#999"></u-icon> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付方式 -->
|
||||
<view class="card pay-card">
|
||||
<view class="section-title">支付方式</view>
|
||||
<view
|
||||
class="payItem acea-row row-middle v12-justify-between"
|
||||
style="flex-wrap: nowrap; margin-top: 20rpx"
|
||||
@click="payItem('weixin')"
|
||||
>
|
||||
<view class="name acea-row v12-font-24 ">
|
||||
<!-- <view class="iconfont icon-weixin2" :class="active === 'weixin' ? 'bounceIn' : ''"></view> -->
|
||||
<image style="flex-shrink: 0;width: 32rpx;height: 32rpx;margin-right: 10rpx;" :src="webUrl+'/orderIcon/微信支付.png'" mode=""></image>
|
||||
微信支付
|
||||
</view>
|
||||
<view class="tip"></view>
|
||||
<label class="radio">
|
||||
<radio style="transform: scale(0.7);" value="" :checked="active === 'weixin'" color="#C52733"/>
|
||||
<text></text>
|
||||
</label>
|
||||
</view>
|
||||
<u-divider></u-divider>
|
||||
<view
|
||||
class="payItem acea-row row-middle v12-justify-between"
|
||||
style="flex-wrap: nowrap;"
|
||||
@click="payItem('yue')"
|
||||
>
|
||||
<view class="name acea-row v12-font-24">
|
||||
<image style="flex-shrink: 0;width: 32rpx;height: 32rpx;margin-right: 10rpx;" :src="webUrl+'/orderIcon/余额宝.png'" mode=""></image>
|
||||
余额支付
|
||||
</view>
|
||||
<!-- <view class="tip">可用余额:{{ userInfo.nowMoney ? force2Decimal(userInfo.nowMoney) : 0.00 }}</view> -->
|
||||
<label class="radio">
|
||||
<radio style="transform: scale(0.7);" value="" :checked="active === 'yue'" color="#C52733"/>
|
||||
<text></text>
|
||||
</label>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 退改规则 -->
|
||||
<view class="card text-card">
|
||||
<view class="section-title">退改规则</view>
|
||||
<view class="plain-text v12-font-26">
|
||||
根据商家政策,与商家确认入住时间前可免费取消;如若确认入住后需要更改入住时间,可需联系客服,与商家商议新的入住时间;若与商家确认入住时间后因取消/退订,则根据不同阶段进行退款。
|
||||
</view>
|
||||
<view class="v12-mt-4">
|
||||
<view class="section-title">预定说明</view>
|
||||
<view class="plain-text">
|
||||
订单生效规则:订单需商家确认后方可生效,确认结果将通过短信通知。您请务必在订单生效后再前往商家办理入住,以免影响您的行程。
|
||||
</view>
|
||||
<view class="plain-text">
|
||||
服务条款说明:预订单由香道滇平台提供,为保障您的权益,请仔细阅读《香道平台旅居预订服务规则》。旅居服务由对应旅居服务提供者(旅居管家/旅居商家)提供。该业务的实际运营及相关责任,由旅居商家基于签约主体公司承担。
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bottom-space"></view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 底部栏 -->
|
||||
<view class="bottom-bar">
|
||||
<view class="total">
|
||||
<text>合计:</text>
|
||||
<text class="highlight">
|
||||
<text class="v12-font-20">¥</text>{{ orderInfo.priceGroup.totalPrice }}
|
||||
</text>
|
||||
</view>
|
||||
<view class="bar-actions">
|
||||
<view class="mini-btn" @click="contactMerchant">联系商家</view>
|
||||
<view class="buy-btn" @click="subscribePay">立即购买</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 日期选择器(简单占位) -->
|
||||
<u-calendar v-model="showCalendar" mode="range" :min-date="minDate" @confirm="onDateConfirm" />
|
||||
<passkeyborad
|
||||
v-if="isShowPayPwdPop"
|
||||
ref='payPwdPop'
|
||||
showMoney
|
||||
:money="orderInfo.priceGroup.totalPrice"
|
||||
:show="isShowPayPwdPop"
|
||||
@close="pwdPopClose"
|
||||
@finish="pwdPopFinish"
|
||||
></passkeyborad>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { createJiaLouOrder, createJiaLouOrderPay } from '@/api/qianxian'
|
||||
import buyMixins from '../mixins/buyMixins'
|
||||
import blPaymentPasswordInput from '@/components/blPaymentPasswordInput.vue'
|
||||
import {mapGetters} from "vuex"
|
||||
import passkeyborad from '@/components/yzc-paykeyboard/yzc-paykeyboard'
|
||||
export default {
|
||||
name: 'SubmitOrder',
|
||||
mixins: [buyMixins],
|
||||
components: {
|
||||
blPaymentPasswordInput,
|
||||
passkeyborad
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
from: this.$deviceType,
|
||||
webUrl: this.$VUE_APP_RESOURCES_URL,
|
||||
form: {
|
||||
name: '',
|
||||
phone: '',
|
||||
payWay: 'wechat',
|
||||
start: '2025-08-17',
|
||||
end: '2025-08-23',
|
||||
id: ''
|
||||
},
|
||||
showCalendar: false,
|
||||
minDate: this.formatDate(new Date()),
|
||||
orderInfo: {},
|
||||
payPassword: null,
|
||||
isShowPayPwdPop: false
|
||||
}
|
||||
},
|
||||
onLoad(opts) {
|
||||
const { id, orderStartDate, orderEndDate } = opts
|
||||
this.form.start = orderStartDate
|
||||
this.form.end = orderEndDate
|
||||
this.form.id = id
|
||||
this.getOrderConfim()
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["userInfo", "storeItems"]),
|
||||
dateRangeText() {
|
||||
return this.formatDisplay(this.form.start) + ' ~ ' + this.formatDisplay(this.form.end)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
pwdPopClose() {
|
||||
this.isShowPayPwdPop = false
|
||||
},
|
||||
pwdPopFinish(payPwd) {
|
||||
this.payPassword = payPwd
|
||||
this.createOrder(true)
|
||||
},
|
||||
chooseDate() { this.showCalendar = true },
|
||||
onDateConfirm(e) {
|
||||
const [start, end] = e;
|
||||
this.form.start = start
|
||||
this.form.end = end
|
||||
this.showCalendar = false
|
||||
},
|
||||
formatDisplay(dateStr) {
|
||||
if (!dateStr) return ''
|
||||
const [y, m, d] = dateStr.split('-')
|
||||
return `${y}年${m}月${d}日`
|
||||
},
|
||||
formatDate(d) {
|
||||
const y = d.getFullYear()
|
||||
const m = String(d.getMonth()+1).padStart(2, '0')
|
||||
const day = String(d.getDate()).padStart(2, '0')
|
||||
return `${y}-${m}-${day}`
|
||||
},
|
||||
contactMerchant() {
|
||||
uni.showToast({ title: '已为您接入管家', icon: 'none' })
|
||||
},
|
||||
submitOrder() {
|
||||
if (!this.form.name || !this.form.phone) {
|
||||
uni.showToast({ title: '请完整填写信息', icon: 'none' })
|
||||
return
|
||||
}
|
||||
uni.showToast({ title: '下单成功(示意)', icon: 'success' })
|
||||
},
|
||||
getOrderConfim() {
|
||||
createJiaLouOrder({
|
||||
travelGroupProductId: this.form.id,
|
||||
orderStartDate: this.form.start,
|
||||
orderEndDate: this.form.end
|
||||
}).then(res => {
|
||||
if (res.status === 200) {
|
||||
this.orderInfo = res.data
|
||||
// uni.showToast({ title: '下单成功(示意)', icon: 'success' })
|
||||
} else {
|
||||
// uni.showToast({ title: res.msg || '下单失败', icon: 'none' })
|
||||
}
|
||||
})
|
||||
},
|
||||
createOrder(isyue) {
|
||||
if (!this.active) {
|
||||
uni.showToast({
|
||||
title: "请选择支付方式",
|
||||
icon: "none",
|
||||
duration: 2000
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!/^1(3|4|5|7|8|9|6)\d{9}$/.test(this.form.phone)) {
|
||||
uni.showToast({
|
||||
title: "请填写正确的手机号",
|
||||
icon: "none",
|
||||
duration: 2000
|
||||
})
|
||||
return;
|
||||
}
|
||||
if (!/^[\u4e00-\u9fa5\w]{2,16}$/.test(this.form.name)) {
|
||||
uni.showToast({
|
||||
title: "请填写您的真实姓名",
|
||||
icon: "none",
|
||||
duration: 2000
|
||||
})
|
||||
return
|
||||
}
|
||||
// 判断如果是余额支付,先要输入支付密码
|
||||
if (this.active == 'yue' && !isyue) {
|
||||
// 先判断用户是否绑定过手机
|
||||
if (this.userInfo.phone) {
|
||||
// 再判断用户是否设置过支付密码
|
||||
if (this.userInfo.hasPwdPay) {
|
||||
// 显示输入支付密码
|
||||
this.isShowPayPwdPop = true
|
||||
} else {
|
||||
// 设置支付密码
|
||||
this.$yrouter.push("/pkg_user/views/payPassword?isSetMode=true")
|
||||
}
|
||||
} else {
|
||||
// 跳转到绑定手机
|
||||
this.$yrouter.push("/pkg_user/views/bindPhone")
|
||||
}
|
||||
return
|
||||
}
|
||||
uni.showLoading({
|
||||
title: "生成订单中"
|
||||
})
|
||||
let from = {}
|
||||
if (this.$deviceType == "app") {
|
||||
from.from = "app"
|
||||
}
|
||||
const params = {
|
||||
key: this.orderInfo.orderKey,
|
||||
realName: this.form.name,
|
||||
phone: this.form.phone,
|
||||
from: this.from,
|
||||
payType: this.active,
|
||||
passwordPay: this.payPassword
|
||||
// ...from
|
||||
}
|
||||
//余额支付的支付密码
|
||||
if (this.active == 'yue') {
|
||||
params.passwordPay = this.payPassword
|
||||
}
|
||||
var that = this
|
||||
createJiaLouOrderPay(params).then(res => {
|
||||
uni.hideLoading()
|
||||
const data = res.data
|
||||
switch (data.status) {
|
||||
case "ORDER_EXIST":
|
||||
case "EXTEND_ORDER":
|
||||
uni.showToast({
|
||||
title: res.msg,
|
||||
icon: "none",
|
||||
duration: 2000
|
||||
})
|
||||
this.$yrouter.replace({
|
||||
path: "/pages/order/OrderDetails/index?isGroup=1",
|
||||
query: {
|
||||
id: data.result.orderId
|
||||
}
|
||||
})
|
||||
break;
|
||||
case "PAY_DEFICIENCY":
|
||||
break;
|
||||
case "PAY_ERROR":
|
||||
uni.showToast({
|
||||
title: res.msg,
|
||||
icon: "none",
|
||||
duration: 2000
|
||||
})
|
||||
this.$yrouter.replace({
|
||||
path: "/pages/order/OrderDetails/index?isGroup=1",
|
||||
query: {
|
||||
id: data.result.orderId
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "SUCCESS":
|
||||
uni.showToast({
|
||||
title: res.msg,
|
||||
icon: "none",
|
||||
duration: 2000
|
||||
})
|
||||
this.$yrouter.replace({
|
||||
path: "/pages/order/OrderDetails/index?isGroup=1",
|
||||
query: {
|
||||
id: data.result.orderId
|
||||
}
|
||||
})
|
||||
break;
|
||||
case "WECHAT_H5_PAY":
|
||||
// H5支付
|
||||
this.$yrouter.replace({
|
||||
path: "/pages/order/OrderDetails/index?isGroup=1",
|
||||
query: {
|
||||
id: data.result.orderId
|
||||
}
|
||||
})
|
||||
break;
|
||||
case "WECHAT_PAY":
|
||||
// 小程序支付
|
||||
weappPay(data.result.jsConfig).finally(() => {
|
||||
this.$yrouter.replace({
|
||||
path: "/pages/order/OrderDetails/index?isGroup=1",
|
||||
query: {
|
||||
id: data.result.orderId
|
||||
}
|
||||
})
|
||||
})
|
||||
break;
|
||||
case "WECHAT_APP_PAY":
|
||||
// APP支付
|
||||
weappPay(data.result.jsConfig).finally(() => {
|
||||
this.$yrouter.replace({
|
||||
path: "/pages/order/OrderDetails/index?isGroup=1",
|
||||
query: {
|
||||
id: data.result.orderId
|
||||
}
|
||||
});
|
||||
})
|
||||
break;
|
||||
}
|
||||
}).catch(err => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: err.msg ||
|
||||
err.response.data.msg ||
|
||||
err.response.data.message ||
|
||||
"创建订单失败",
|
||||
icon: "none",
|
||||
duration: 2000
|
||||
})
|
||||
}).finally(function () {
|
||||
that.isShowPayPwdPop = false
|
||||
that.$refs.payPwdPop.clear()
|
||||
that.$refs.payPwdPop.close()
|
||||
})
|
||||
},
|
||||
subscribePay() {
|
||||
uni.requestSubscribeMessage({
|
||||
tmplIds: [
|
||||
'7O3wKw7_D4t7yfSOlvecKuOQP8QEPY88uBx2FJg43HE',
|
||||
'TSmTnGibZ8IxWCiRWOvLxha6-0u7tE-V1-WbDCiPkKU',
|
||||
'9Q6xLHe6HyjkU5Zn5k_2zxYPf2y4MxVyUbOSW8pcZRU'
|
||||
],
|
||||
complete: () => this.createOrder(false)
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.submit-order { min-height: 100vh; }
|
||||
.page-scroll { height: calc(100vh - 120rpx); }
|
||||
.card { background: #fff; border-radius: 24rpx; margin: 24rpx; padding: 24rpx; }
|
||||
.product-card { display: flex; }
|
||||
.thumb { width: 160rpx; height: 160rpx; border-radius: 16rpx; }
|
||||
.info { flex: 1; margin-left: 20rpx; }
|
||||
.title { font-size: 28rpx; color: #333; line-height: 40rpx; font-weight: 600; }
|
||||
.price-row { margin-top: 8rpx; display: flex; align-items: baseline; }
|
||||
.label { font-size: 24rpx; color: #666; }
|
||||
.price { color: #E53935; font-size: 34rpx; font-weight: 700; }
|
||||
.notice { margin-top: 12rpx; font-size: 22rpx; color: #999; }
|
||||
|
||||
.section-title { font-size: 28rpx; color: #111; font-weight: 600; margin-bottom: 12rpx; }
|
||||
.form-item { margin-bottom: 20rpx; display: flex; align-items: center; }
|
||||
.form-label { width: 120rpx; display: block; font-size: 24rpx; color: #666; margin-bottom: 0; }
|
||||
.date-row { display: flex; align-items: center; justify-content: space-between; background: #fff; border-radius: 16rpx; padding: 20rpx; }
|
||||
.date-val { font-size: 26rpx; color: #333; }
|
||||
|
||||
.radio-item { margin-bottom: 16rpx; }
|
||||
.text-card .plain-text { font-size: 26rpx; color: #666; line-height: 40rpx; letter-spacing: 2px;}
|
||||
|
||||
.bottom-space { height: 140rpx; }
|
||||
.bottom-bar { position: fixed; left: 0; right: 0; bottom: 0; background: #fff; border-top: 1rpx solid #eee; display: flex; align-items: center; justify-content: space-between; padding: 16rpx 24rpx; }
|
||||
.total { font-size: 28rpx; color: #111; font-weight: 700; }
|
||||
.total .highlight { color: #C52733; font-weight: 700; }
|
||||
.bar-actions { display: flex; gap: 16rpx; }
|
||||
.mini-btn { padding: 16rpx 22rpx; border: 1rpx solid #ccc; border-radius: 32rpx; font-size: 26rpx; color: #333; }
|
||||
.buy-btn { padding: 16rpx 28rpx; border-radius: 32rpx; background: #C52733; color: #fff; font-size: 26rpx; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user