You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
608 lines
14 KiB
608 lines
14 KiB
<template>
|
|
<view class="peiwan">
|
|
<view class="peiwan-hd">
|
|
<view class="title">约玩项目</view>
|
|
<view class="content">
|
|
<view class="item" @click="clickItem(idx)" :class="clickIndex == idx?(a.type==1?'item-on item-active':'item-active'):(a.type==1?'item-on':'')" v-for="(a,idx) in sellerServiceList" :key="idx">
|
|
<view class="name">{{a.name}}</view>
|
|
<view class="price">{{a.price}}元</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="peiwan-hd">
|
|
<view class="title">服务时长</view>
|
|
<view class="fuwu">
|
|
<view class="item">
|
|
<view class="a">服务时长</view>
|
|
<view class="b" if="if">
|
|
<u-number-box v-model="duration" @change="valChange"></u-number-box>
|
|
</view>
|
|
</view>
|
|
<view class="item">
|
|
<view class="a">服务金额</view>
|
|
<view class="b">
|
|
<text>¥{{sellerServiceList && sellerServiceList.length?sellerServiceList[clickIndex].price*duration: 0}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="peiwan-hd">
|
|
<view class="title">服务信息</view>
|
|
<view class="info">
|
|
<view class="item">
|
|
<view class="a">联系人</view>
|
|
<view class="b">
|
|
<input v-model="linkPerson" type="text" placeholder="请输入" />
|
|
</view>
|
|
</view>
|
|
<view class="item">
|
|
<view class="a">见面位置</view>
|
|
<view class="b" @click="openLocation()">
|
|
<view class="txt" :class="location?'':'txt-on'">{{location?location:'请选择位置'}}</view>
|
|
<image src="@/static/icon-arrow.png"></image>
|
|
</view>
|
|
</view>
|
|
<view class="item">
|
|
<view class="a">详细地址</view>
|
|
<view class="b" @click="openLocation()">
|
|
<view class="txt" :class="address?'':'txt-on'">{{address?address:'请选择位置'}}</view>
|
|
<image src="@/static/icon-arrow.png"></image>
|
|
</view>
|
|
</view>
|
|
<view class="item">
|
|
<view class="a">见面时间</view>
|
|
<view class="b" @click="openTime()">
|
|
<view class="txt" :class="meettime?'':'txt-on'">{{meettime?meettime:'请选择'}}</view>
|
|
<image src="@/static/icon-arrow.png"></image>
|
|
</view>
|
|
</view>
|
|
<view class="item">
|
|
<view class="a">联系电话</view>
|
|
<view class="b">
|
|
<input v-model="phone" type="number" placeholder="请输入" />
|
|
</view>
|
|
</view>
|
|
<view class="item">
|
|
<view class="a">微信号</view>
|
|
<view class="b">
|
|
<input v-model="wxcode" type="text" placeholder="请输入" />
|
|
</view>
|
|
</view>
|
|
<view class="item">
|
|
<view class="a">距离陪玩师</view>
|
|
<view class="b">
|
|
{{distance?(distance+"km"):0}}
|
|
</view>
|
|
</view>
|
|
<view class="item">
|
|
<view class="a">路费<text>{{lufei}}元/km</text></view>
|
|
<view class="b">
|
|
¥{{lufeiTotal}}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="peiwan-hd">
|
|
<view class="title">支付方式</view>
|
|
<view class="pay" v-if="payInfo && payInfo.length >= 1">
|
|
<template v-for="(a,i) in payInfo">
|
|
<view class="item" v-if="a=='wx-1' || a=='ali-1'" :key="i" :class="tabIndex == i?'item-on':''" @click="tabItem(i,a)">
|
|
<view class="a" v-if="a=='wx-1'"><image src="@/static/wxpay.png"></image>微信支付</view>
|
|
<view class="a" v-if="a=='ali-1'"><image src="@/static/zfb.png"></image>支付宝支付</view>
|
|
<view class="b">
|
|
<image class="img1" src="@/static/icon-check.png"></image>
|
|
<image class="img2" src="@/static/icon-check-on.png"></image>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
</view>
|
|
</view>
|
|
<view class="peiwan-fd">
|
|
<view class="price">
|
|
合计:¥{{total}}<text>通过阿里云提供计算服务</text>
|
|
</view>
|
|
<view class="btn" @click="toCreate()">立即支付</view>
|
|
</view>
|
|
<u-picker v-model="show" mode="time" :params="params" @cancel="cancel" @confirm="confirm"></u-picker>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
data() {
|
|
return {
|
|
show: false,
|
|
tabIndex: -1,
|
|
duration: 1,
|
|
clickIndex: 0,
|
|
id: "",
|
|
payInfo: [],
|
|
payType: "",
|
|
wxcode: "",
|
|
phone: "",
|
|
address: "",
|
|
meettime: "",
|
|
linkPerson: "",
|
|
location: "",
|
|
lat: "",
|
|
lon: "",
|
|
lufeiTotal: 0,
|
|
distance: 0,
|
|
sellerServiceList: [],
|
|
params: {
|
|
year: true,
|
|
month: true,
|
|
day: true,
|
|
hour: true,
|
|
minute: true,
|
|
second: true
|
|
},
|
|
lufei: 0,
|
|
total: 0
|
|
};
|
|
},
|
|
onLoad(o) {
|
|
this.id = o.id;
|
|
this.userSellerServiceList();
|
|
this.getConfigData();
|
|
},
|
|
methods: {
|
|
calculateDistance(lat1, lon1, lat2, lon2) {
|
|
const radius = 6371; // 地球半径,单位为公里
|
|
|
|
const deltaLat = (lat2 - lat1) * (Math.PI / 180);
|
|
const deltaLon = (lon2 - lon1) * (Math.PI / 180);
|
|
|
|
const lat1Rad = lat1 * (Math.PI / 180);
|
|
const lat2Rad = lat2 * (Math.PI / 180);
|
|
|
|
const a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
|
|
Math.cos(lat1Rad) * Math.cos(lat2Rad) *
|
|
Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2);
|
|
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
const distance = radius * c;
|
|
|
|
return distance;
|
|
},
|
|
cancel() {
|
|
this.show = false;
|
|
},
|
|
confirm(e) {
|
|
console.log(e)
|
|
this.meettime = e.year+"-"+e.month+"-"+e.day+" "+e.hour+":"+e.minute+":"+e.second
|
|
this.show = false;
|
|
},
|
|
openLocation() {
|
|
const that = this;
|
|
if(that.isClick == false){
|
|
return ;
|
|
}
|
|
that.isClick = false
|
|
uni.getLocation({
|
|
type: 'gcj02',
|
|
success: function (res) {
|
|
const latitude = res.latitude;
|
|
const longitude = res.longitude;
|
|
console.log('success',res);
|
|
uni.chooseLocation({
|
|
latitude: latitude,
|
|
longitude: longitude,
|
|
success: function (res) {
|
|
that.isClick = true;
|
|
console.log('success',res);
|
|
that.lat = res.latitude;
|
|
that.lon = res.longitude;
|
|
that.address = res.address;
|
|
that.location = res.name;
|
|
that.distance = that.calculateDistance(latitude,longitude,that.lat,that.lon).toFixed(3);
|
|
that.lufeiTotal = ((that.distance)*that.lufei).toFixed(2);
|
|
if(that.sellerServiceList){
|
|
that.total = Number(that.sellerServiceList[that.clickIndex].price*that.duration)+Number(that.lufeiTotal)
|
|
}
|
|
|
|
},fail(err) {
|
|
that.isClick = true;
|
|
console.log(err)
|
|
}
|
|
});
|
|
},fail(err) {
|
|
that.isClick = true;
|
|
console.log(err)
|
|
}
|
|
});
|
|
},
|
|
openTime() {
|
|
this.show = true;
|
|
},
|
|
clickItem(index) {
|
|
this.clickIndex = index
|
|
if(this.sellerServiceList){
|
|
this.total = this.sellerServiceList[this.clickIndex].price*this.duration+this.lufeiTotal
|
|
}
|
|
},
|
|
valChange(e) {
|
|
console.log(e)
|
|
this.total = this.sellerServiceList[this.clickIndex].price*(this.duration)+Number(this.lufeiTotal)
|
|
},
|
|
tabItem(index,a){
|
|
this.tabIndex = index;
|
|
this.payType = a
|
|
},
|
|
//字典查询
|
|
async getConfigData() {
|
|
const that = this;
|
|
let res1 = await that.$api.getConfigData({dictType: 'CONFIG_PAY_STATUS'});
|
|
let res2 = await that.$api.getConfigData({dictType: 'CONFIG_TRAVEL_EXPENSES'});
|
|
if(res1.data.content){
|
|
this.payInfo = res1.data.content.split(",");
|
|
}
|
|
if(res2.data.content){
|
|
this.lufei = res2.data.content
|
|
console.log(this.lufei)
|
|
}
|
|
},
|
|
async userSellerServiceList() {
|
|
const { code, data , msg } = await this.$api.userSellerServiceList({
|
|
userId: uni.getStorageSync("userInfo").id,
|
|
sellerId: this.id,
|
|
lat: uni.getStorageSync("jingweiInfo").latitude,
|
|
lon: uni.getStorageSync("jingweiInfo").longitude
|
|
});
|
|
if(code == 200){
|
|
this.sellerServiceList = data.serviceList;
|
|
if(this.sellerServiceList){
|
|
this.total = this.sellerServiceList[this.clickIndex].price*this.duration+this.lufeiTotal
|
|
}
|
|
}else{
|
|
uni.showToast({
|
|
title: msg,
|
|
position: "bottom",
|
|
icon: "none",
|
|
})
|
|
}
|
|
},
|
|
//创建订单
|
|
async toCreate() {
|
|
const that = this;
|
|
if(!this.payType){
|
|
uni.showToast({
|
|
icon: "none",
|
|
position: "bottom",
|
|
title: "请选择支付方式"
|
|
})
|
|
return ;
|
|
}
|
|
|
|
if(!this.location){
|
|
uni.showToast({
|
|
icon: "none",
|
|
position: "bottom",
|
|
title: "见面位置"
|
|
})
|
|
return ;
|
|
}
|
|
|
|
if(!this.meettime){
|
|
uni.showToast({
|
|
icon: "none",
|
|
position: "bottom",
|
|
title: "见面时间不能为空!"
|
|
})
|
|
return ;
|
|
}
|
|
if(!this.phone){
|
|
uni.showToast({
|
|
icon: "none",
|
|
position: "bottom",
|
|
title: "联系电话不能为空!"
|
|
})
|
|
return ;
|
|
}
|
|
if(!this.wxcode){
|
|
uni.showToast({
|
|
icon: "none",
|
|
position: "bottom",
|
|
title: "微信号不能为空!"
|
|
})
|
|
return ;
|
|
}
|
|
uni.showLoading({
|
|
title: "正在支付"
|
|
})
|
|
const {code, data, msg} = await that.$api.preCreateOrder({
|
|
userId: uni.getStorageSync("userInfo").id,
|
|
acceptUserId: this.id,
|
|
configId: that.sellerServiceList[that.clickIndex].id,
|
|
duration: that.duration,
|
|
linkPerson: that.linkPerson,
|
|
location: that.location,
|
|
lon: that.lon,
|
|
lat: that.lat,
|
|
address: that.address,
|
|
meettime: that.meettime,
|
|
phone: that.phone,
|
|
wxcode: that.wxcode,
|
|
distance: that.distance
|
|
})
|
|
if(code == 200){
|
|
that.toPay(msg);
|
|
}else{
|
|
uni.showToast({
|
|
icon: "none",
|
|
position: "bottom",
|
|
title: msg
|
|
})
|
|
}
|
|
},
|
|
//支付
|
|
async toPay(outTradeNo) {
|
|
const that = this;
|
|
const {code, data, msg} = await that.$api.paymentOrder({
|
|
payType: that.payType =='wx-1'?1:2,
|
|
outTradeNo
|
|
})
|
|
if(code == 200){
|
|
uni.hideLoading()
|
|
uni.requestPayment({
|
|
provider: that.payType == 'ali-1'?'alipay':'wxpay',
|
|
orderInfo: that.payType == 'ali-1'?data.orderInfo:JSON.parse(data.orderInfo), //微信、支付宝订单数据 【注意微信的订单信息,键值应该全部是小写,不能采用驼峰命名】
|
|
success: function (res) {
|
|
uni.showToast({
|
|
title: "支付成功"
|
|
})
|
|
setTimeout(()=>{
|
|
uni.redirectTo({
|
|
url: "/pages/users/order/index"
|
|
})
|
|
},2000)
|
|
},
|
|
fail: function (err) {
|
|
console.log('fail:' + JSON.stringify(err));
|
|
uni.showToast({
|
|
icon: "error",
|
|
title: "支付失败"
|
|
})
|
|
setTimeout(()=>{
|
|
uni.redirectTo({
|
|
url: "/pages/users/order/index"
|
|
})
|
|
},2000)
|
|
}
|
|
});
|
|
}else{
|
|
uni.hideLoading();
|
|
uni.showToast({
|
|
icon: "none",
|
|
position: "bottom",
|
|
title: msg
|
|
})
|
|
}
|
|
},
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.peiwan{
|
|
padding: 0 25rpx 160rpx;
|
|
overflow: hidden;
|
|
&-fd{
|
|
background-color: #FFFFFF;
|
|
width: 100%;
|
|
padding: 30rpx 25rpx;
|
|
box-sizing: border-box;
|
|
position: fixed;
|
|
left: 0;
|
|
bottom: 0;
|
|
z-index: 22;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
.price{
|
|
font-weight: 500;
|
|
font-size: 30rpx;
|
|
color: #222222;
|
|
text{
|
|
display: block;
|
|
font-size: 24rpx;
|
|
color: #999999;
|
|
text-align: left;
|
|
margin-top: 10rpx;
|
|
}
|
|
}
|
|
.btn{
|
|
width: 230rpx;
|
|
line-height: 80rpx;
|
|
background: linear-gradient(0deg, #000000, #3D3B38);
|
|
box-shadow: 0px 4rpx 18rpx 0px rgba(42,41,39,0.34);
|
|
border-radius: 80rpx;
|
|
text-align: center;
|
|
font-weight: 400;
|
|
font-size: 30rpx;
|
|
color: #FFFFFF;
|
|
}
|
|
}
|
|
&-hd{
|
|
overflow: hidden;
|
|
.title{
|
|
font-weight: 500;
|
|
font-size: 32rpx;
|
|
color: #222222;
|
|
margin-top: 30rpx;
|
|
}
|
|
.pay{
|
|
padding: 20rpx 30rpx;
|
|
background: #FFFFFF;
|
|
border-radius: 20rpx;
|
|
margin-top: 20rpx;
|
|
.item{
|
|
padding: 10rpx 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
font-weight: 400;
|
|
font-size: 28rpx;
|
|
color: #333333;
|
|
.a{
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
image{
|
|
width: 60rpx;
|
|
height: 60rpx;
|
|
margin-right: 10rpx;
|
|
}
|
|
}
|
|
.b{
|
|
font-size: 28rpx;
|
|
color: #CCCCCC;
|
|
display: flex;
|
|
align-items: center;
|
|
image{
|
|
width: 32rpx;
|
|
height: 32rpx;
|
|
margin-left: 20rpx;
|
|
}
|
|
.img1{
|
|
display: block;
|
|
}
|
|
.img2{
|
|
display: none;
|
|
}
|
|
}
|
|
&-on{
|
|
.b{
|
|
.img1{
|
|
display: none;
|
|
}
|
|
.img2{
|
|
display: block;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.info{
|
|
width: 100%;
|
|
background: #FFFFFF;
|
|
border-radius: 20rpx;
|
|
padding: 0 30rpx;
|
|
box-sizing: border-box;
|
|
margin-top: 20rpx;
|
|
.item{
|
|
padding: 35rpx 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
border-top: 1px solid #EAEAEA;
|
|
&:first-child{
|
|
border-top-color: #FFFFFF;
|
|
}
|
|
.a{
|
|
font-weight: 500;
|
|
font-size: 30rpx;
|
|
color: #222222;
|
|
text{
|
|
font-size: 24rpx;
|
|
color: #999999;
|
|
margin-left: 10rpx;
|
|
}
|
|
}
|
|
.b{
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-end;
|
|
font-size: 28rpx;
|
|
color: #222222;
|
|
image{
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
}
|
|
input{
|
|
width: 100%;
|
|
text-align: right;
|
|
line-height: 50rpx;
|
|
padding: 0 20rpx;
|
|
box-sizing: border-box;
|
|
height: 50rpx;
|
|
font-size: 28rpx;
|
|
color: #222222;
|
|
}
|
|
.txt{
|
|
font-weight: 500;
|
|
font-size: 28rpx;
|
|
color: #212121;
|
|
margin-left: 30rpx;
|
|
&-on{
|
|
color: #808080;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.fuwu{
|
|
width: 100%;
|
|
background: #FFFFFF;
|
|
border-radius: 20rpx;
|
|
padding: 20rpx 30rpx;
|
|
box-sizing: border-box;
|
|
margin-top: 20rpx;
|
|
.item{
|
|
padding: 10rpx 0;
|
|
display: flex;
|
|
align-items: center;
|
|
.a{
|
|
font-weight: 500;
|
|
font-size: 30rpx;
|
|
color: #222222;
|
|
margin-right: 50rpx;
|
|
}
|
|
.b{
|
|
flex: 1;
|
|
text{
|
|
font-weight: 500;
|
|
font-size: 28rpx;
|
|
color: #E70C0C;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.content{
|
|
margin-top: 20rpx;
|
|
overflow: hidden;
|
|
width: 110%;
|
|
.item{
|
|
width: 230rpx;
|
|
background: url(@/static/icon-xianxia.png) center top no-repeat;
|
|
background-size: contain;
|
|
float: left;
|
|
text-align: left;
|
|
padding: 30rpx;
|
|
box-sizing: border-box;
|
|
border: 1px solid #F3F4F5;
|
|
&-on{
|
|
background: url(@/static/icon-xianshang.png) center top no-repeat;
|
|
background-size: contain;
|
|
}
|
|
&-active{
|
|
border: 1px solid #000;
|
|
}
|
|
.name{
|
|
font-weight: 500;
|
|
font-size: 30rpx;
|
|
color: #222222;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
}
|
|
.price{
|
|
font-weight: 500;
|
|
font-size: 24rpx;
|
|
color: #E70C0C;
|
|
margin-top: 10rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|
|
|