// 获取两个经纬度中间点
getCenterPoint(point1, point2) {
// console.log(point1, point2);
// 角度转弧度(JS 数学函数用弧度计算)
const rad = Math.PI / 180;
const lat1 = Number(point1.lat) * rad;
const lng1 = Number(point1.lng) * rad;
const lat2 = Number(point2.lat) * rad;
const lng2 = Number(point2.lng) * rad;
// 球面中点计算公式
const Bx = Math.cos(lat2) * Math.cos(lng2 - lng1);
const By = Math.cos(lat2) * Math.sin(lng2 - lng1);
const latMid = Math.atan2(
Math.sin(lat1) + Math.sin(lat2),
Math.sqrt((Math.cos(lat1) + Bx) ** 2 + By ** 2)
);
const lngMid = lng1 + Math.atan2(By, Math.cos(lat1) + Bx);
// 弧度转回角度
return {
lat: Number((latMid / rad).toFixed(6)),
lng: Number((lngMid / rad).toFixed(6))
};
},
// 轮询改变当前定位,更新路线
const rollPoling = () =>{
// api接口
accountServiceOrder_detail({orderId: orderId.value}).then(res=>{
//司机到起点
var startRoute = [];
// 接口返回的字符串路线信息
if(res.data.directionDrivingResult.steps){
var start_steps = JSON.parse(res.data.directionDrivingResult.steps)
for (let i = 0; i < start_steps.length; i++) {
const poLen1 = start_steps[i].polyline.split(";");
for (let j = 0; j < poLen1.length; j++) {
console.log();
startRoute.push({
longitude: parseFloat(poLen1[j].split(",")[0]),
latitude: parseFloat(poLen1[j].split(",")[1])
});
}
}
console.log(start_steps);
}
// console.log(startRoute);
// 起点到终点
let datad = res.data.order
var points = [];
var steps = JSON.parse(datad.steps)
for (let i = 0; i < steps.length; i++) {
const poLen = steps[i].polyline.split(";");
for (let j = 0; j < poLen.length; j++) {
points.push({
longitude: parseFloat(poLen[j].split(",")[0]),
latitude: parseFloat(poLen[j].split(",")[1])
});
}
}
if([4,5,6].indexOf(res.data.order.orderStatus) > -1){
scale.value = 17.5
dqLat.value = res.data.order.driverLatitude
dqLon.value = res.data.order.driverLongitude
polyline.value = [ {
points: startRoute,
color: '#104FB9',
width: 10,
arrowLine: true,
}]
markers.value = [
{
id: 1,
longitude: Number(datad.departLongitude),
latitude: Number(datad.departLatitude),
iconPath: '/static/index/start.png',
width: 30,
height: 30,
anchor: {
x: 0.5,
y: 1
},
callout: {
content: '起点-'+(datad.departAddressDetails || datad.departAddress),
color: '#333333',
fontSize: 12,
borderRadius: 8,
bgColor: '#FFFFFF',
padding: 10,
display: 'ALWAYS',
textAlign: 'left',
borderWidth: 1,
borderColor: '#E5E5E5'
}
},
{
id: 2,
longitude: Number(datad.arriveLongitude),
latitude: Number(datad.arriveLatitude),
iconPath: '/static/index/end.png',
width: 30,
height: 30,
anchor: {
x: 0.5,
y: 1
},
callout: {
content: '终点-'+(datad.arriveAddressDetails || datad.arriveAddress),
color: '#333333',
fontSize: 12,
borderRadius: 8,
bgColor: '#FFFFFF',
padding: 10,
display: 'ALWAYS',
textAlign: 'left',
borderWidth: 1,
borderColor: '#E5E5E5'
}
},
{
id: 3,
longitude: Number(datad.driverLongitude),
latitude: Number(datad.driverLatitude),
iconPath: '/static/driverIcon.png',
width: 40,
height: 40,
anchor: {
x: 0.5,
y: 1
},
callout: {
content: res.data.directionDrivingResult.distance+'km',
color: '#333333',
fontSize: 12,
borderRadius: 8,
bgColor: '#FFFFFF',
padding: 10,
display: 'ALWAYS',
textAlign: 'left',
borderWidth: 1,
borderColor: '#E5E5E5'
}
},
]
}else{
// 完成的路线
let endRote = []
if(res.data.order.orderStatus == 7){
accountServiceOrder_serviceOrderRouteLonLat({orderId: orderId.value}).then(res=>{
const poLen2 = res.data.split(";");
for (let j = 0; j < poLen2.length; j++) {
endRote.push({
longitude: parseFloat(poLen2[j].split(",")[0]),
latitude: parseFloat(poLen2[j].split(",")[1])
});
}
console.log(endRote);
polyline.value = [{
points: endRote,
color: '#FF6B35',
width: 10,
arrowLine: true,
}]
})
}else{
polyline.value = [{
points: points,
color: '#FF6B35',
width: 10,
arrowLine: true,
}]
}
markers.value = [
{
id: 1,
longitude: Number(datad.departLongitude),
latitude: Number(datad.departLatitude),
iconPath: '/static/index/start.png',
width: 30,
height: 30,
anchor: {
x: 0.5,
y: 1
},
callout: {
content: '起点-'+(datad.departAddressDetails || datad.departAddress),
color: '#333333',
fontSize: 12,
borderRadius: 8,
bgColor: '#FFFFFF',
padding: 10,
display: 'ALWAYS',
textAlign: 'left',
borderWidth: 1,
borderColor: '#E5E5E5'
}
},
{
id: 2,
longitude: Number(datad.arriveLongitude),
latitude: Number(datad.arriveLatitude),
iconPath: '/static/index/end.png',
width: 30,
height: 30,
anchor: {
x: 0.5,
y: 1
},
callout: {
content: '终点-'+(datad.arriveAddressDetails || datad.arriveAddress),
color: '#333333',
fontSize: 12,
borderRadius: 8,
bgColor: '#FFFFFF',
padding: 10,
display: 'ALWAYS',
textAlign: 'left',
borderWidth: 1,
borderColor: '#E5E5E5'
}
},
]
}
if(res.data.routeAddressList.length > 0){
res.data.routeAddressList.forEach((el,index) =>{
markers.value.push({
id: 10 * index,
longitude: Number(el.routeAddressLon),
latitude: Number(el.routeAddressLat),
iconPath: '/static/index/tujingdian.png',
width: 12,
height: 30,
anchor: {
x: 0.5,
y: 1
},
callout: {
content: '途经点-'+el.routeAddress,
color: '#333333',
fontSize: 10,
borderRadius: 8,
bgColor: '#FFFFFF',
padding: 10,
display: 'ALWAYS',
textAlign: 'left',
borderWidth: 1,
borderColor: '#E5E5E5'
}
})
})
}
})
}
let pageData = reactive({
detail:{}
})
let totalPrice = ref(0)
let dqLon = ref(null)
let dqLat = ref(null)
let scale = ref(13.5)
let time = ref(null)
const getdata = () =>{
accountServiceOrder_detail({orderId: orderId.value}).then(res=>{
// console.log(res.data.order);
pageData.detail = res.data.order
totalPrice.value = ((res.data.order.payPrice || 0) + (res.data.order.backPaymentMoney || 0)).toFixed(2)
let center = getCenterPoint(
{lat: res.data.order.arriveLatitude, lng: res.data.order.arriveLongitude}, //起点经纬度
{lat: res.data.order.departLatitude, lng: res.data.order.departLongitude} //终点经纬度
)
let radiusNum = Math.abs((res.data.order.arriveLatitude - center.lat) * 100000)
// 动态改变视图缩放
if(radiusNum < 3000){
scale.value = 14
}else if(radiusNum >= 3000 && radiusNum < 6000){
scale.value = 13
}else if(radiusNum >= 6000 && radiusNum < 9000){
scale.value = 12
}else if(radiusNum >= 9000 && radiusNum < 12000){
scale.value = 11
}else if(radiusNum >= 12000){
scale.value = 10
}
dqLat.value = center.lat
dqLon.value = center.lng
rollPoling()
if([3,4,5,6].indexOf(res.data.order.orderStatus) > -1){
time.value = setInterval(()=>{
rollPoling()
},5000)
butShow.value = true
}if(res.data.order.orderStatus == 7){
let newTime = new Date().getTime()
let nobutTime = new Date(res.data.order.finishLimitTime).getTime()
butShow.value = nobutTime > newTime ? true : false
}else{
clearInterval(time.value)
}
})
}
<template>
<view class="order-page">
<!-- 顶部导航栏 -->
<up-navbar safeAreaInsetTop autoBack left-text="返回" bgColor="transparent">
</up-navbar>
<!-- 地图区域 -->
<view class="map-section">
<map class="map" :latitude="dqLat" :longitude="dqLon"
:scale="scale" :show-location="true"
:markers="markers" :polyline="polyline" :enable-zoom="true"
:enable-scroll="true" :enable-rotate="false" :enable-traffic="true"></map>
</view>
<view class="contPart">
<!-- 红色提示横幅 -->
<view class="warning-banner">
<text class="warning-title">温馨提示</text>
<text class="warning-text"> 价格以最终订单结束为准</text>
<view class="radiuDiv"></view>
</view>
<!-- 订单状态卡片 -->
<view class="order-status-card" v-if="[1,2].indexOf(pageData.detail.orderStatus) > -1">
<view class="order-status-left" v-if="pageData.detail.orderStatus == 1">
<text class="order-title">待支付 合计:{{pageData.detail.payPrice}}元</text>
<view class="u-flex-row">
<text class="col999 font28 mar-r10">目的地</text>
<text class="font28 col333"> {{ pageData.detail.arriveAddress || pageData.detail.arriveAddressDetails}}</text>
</view>
</view>
<view class="order-status-left" v-if="pageData.detail.orderStatus == 2">
<text class="order-title">正在寻找司机,请耐心等待</text>
<view class="u-flex-row">
<text class="col999 font28 mar-r10">目的地</text>
<text class="font28 col333"> {{ pageData.detail.arriveAddress || pageData.detail.arriveAddressDetails}}</text>
</view>
</view>
<view class="height-60"></view>
</view>
<view class="order-status-card" v-if="[3,4,5,6,7].indexOf(pageData.detail.orderStatus) > -1">
<view class="dengdai mar-t10" v-if="pageData.detail.orderStatus == 4">
<text class="font40 fontbold">司机正在赶来</text>
</view>
<view class="dengdai mar-t10" v-if="pageData.detail.orderStatus == 5">
<text class="font40 fontbold">司机已到约定上车点</text>
<!-- <text class="font26 mar-t10 colED5858">司机可免费等5分钟,超过五分钟需收取额外等待费用</text> -->
</view>
<view class="dengdai mar-t10 " v-if="pageData.detail.orderStatus == 6">
<text class="font40 fontbold">您已上车,预计{{timeFormat(pageData.detail.appointmentEndTime,'hh:MM')}}到达</text>
<view class="u-flex-row mar-t10">
<text class="col999 font28 mar-r10">正在前往目的地 </text>
<text class="font28 colED5858"> {{pageData.detail.arriveAddressDetails}} </text>
</view>
</view>
<view class="dengdai mar-t10 " v-if="pageData.detail.orderStatus == 7">
<view class="u-flex-row flexbetween">
<text class="font40 fontbold">行程已顺利结束</text>
<view class="u-flex-row" style="align-items: center;" @click="priceShow = !priceShow">
<text class="font32">合计</text>
<text class="font48 priceCol fontbold"> {{totalPrice}} </text>
<text class="font32">元</text>
<u-icon :name="!priceShow ?'arrow-down-fill':'arrow-up-fill'" size="12"></u-icon>
</view>
</view>
<text class="col999 font28 mar-t10">{{pageData.detail.finishTime}}送达 </text>
<view class="bgF7 u-p-20 mar-t20 radiu16" v-if="priceShow">
<view class="u-flex-row flexbetween">
<text class="font32 ">最终订单价</text>
<text class="font32">{{totalPrice}}元</text>
</view>
<text class="col999 font28 mar-t10">总里程{{pageData.detail.kilometreDistance}}公里</text>
<view class="u-flex-row flexbetween mar-t15">
<text class="font32 ">支付金额</text>
<text class="font32">{{pageData.detail.payPrice}}元</text>
</view>
<view class="u-flex-row flexbetween mar-t15" v-if="pageData.detail.backPaymentMoney">
<text class="font32 ">补交金额</text>
<text class="font32">{{pageData.detail.backPaymentMoney}}元</text>
</view>
<view class="u-flex-row flexbetween mar-t15" v-if="pageData.detail.tipPrice">
<text class="font32 ">红包打赏</text>
<text class="font32">{{pageData.detail.tipPrice || 0}}元</text>
</view>
<!-- <text class="col999 font28 mar-t10">2025-10-15 16:10:30 </text> -->
</view>
</view>
<view class="">
<view class="order-status-content">
<view class="">
<text class="font52 fontbold"> {{pageData.detail.licencePlateNumber}} </text>
<text class="col999 font28 mar-t10">
{{ pageData.detail.vehicleColour }} · {{ pageData.detail.vehicleBrand }} | {{ pageData.detail.vehicleSaddleTypeLabel }} · {{ pageData.detail.vehicleTypeName }}
</text>
</view>
<image class="car-image" :src="pageData.detail.vehicleTypeThumb" mode="aspectFit"></image>
</view>
<view class="userPerson flexbetween flexa u-flex-row">
<view class="flexalign u-flex-row">
<u-avatar :src="pageData.detail.driverHead"></u-avatar>
<view class="mar-l15">
<text class="font34 col333 u-m-b-6">{{ pageData.detail.driverName}}</text>
<u-rate :count="5" v-model="pageData.detail.driverStar"
size="15" gutter="1" disabled></u-rate>
</view>
</view>
<view class="flexalign u-flex-row">
<view class="options" @click="collect">
<!-- #A8BDE0 -->
<u-icon name="star" :color="'#104FB9'" size="18" v-if="collTag == 0"></u-icon>
<u-icon name="star-fill" :color="'#104FB9'" size="18" v-if="collTag == 1"></u-icon>
</view>
<view class="options mar-l30" @click="goPhone(pageData.detail.driverPhone)"
v-if="butShow">
<!-- #A8BDE0 -->
<u-icon name="phone-fill" color="#104FB9" size="18"></u-icon>
</view>
</view>
</view>
<view class="opts flexbetween mar-t30 u-flex-row">
<view class="optsIts" @click="help">
<image class="optsIts-img" src="/static/index/order1.png" mode="aspectFill"></image>
<text class="font28 col666 mar-t20">需要帮助</text>
</view>
<view class="optsIts" @click="complainCli">
<image class="optsIts-img" src="/static/index/order2.png" mode="aspectFill"></image>
<text class="font28 col666 mar-t20">{{complaintTag == 0?'投诉司机':'已投诉'}}</text>
</view>
<view class="optsIts" @click="shareRoute">
<image class="optsIts-img2" src="/static/index/order3.png" mode="aspectFill"></image>
<text class="font28 col666 mar-t20">行程分享</text>
</view>
<view class="optsIts" @click="redPackCli">
<image class="optsIts-img" src="/static/index/order4.png" mode="aspectFill"></image>
<text class="font28 col666 mar-t20">红包打赏</text>
</view>
</view>
</view>
</view>
<view class="order-status-card" v-if="[8,9].indexOf(pageData.detail.orderStatus) > -1">
<view class="order-status-left">
<text class="order-title">订单已取消</text>
<!-- <view class="u-flex-row">
<text class="col999 font28 mar-r10">目的地</text>
<text class="font28 col333"> {{pageData.detail.arriveAddressDetails}}</text>
</view> -->
</view>
<!-- <view class="order-status-content">
<view class="">
<text class="waiting-time">已等待15秒</text>
<text class="col999 font28">预计一分钟派给司机</text>
</view>
<image class="car-image" src="/static/index/car1.png" mode="aspectFit"></image>
</view> -->
</view>
<!-- 底部按钮区域 -->
<view class="bgfff height-30"></view>
<view class="bottom-actions" v-if="pageData.detail.orderStatus == 1">
<button class="cancel-btn" hover-class="cancel-btn-hover" @click="noOrderCancel">
<text class="butText">取消订单</text>
</button>
<button class="rebook-btn mar-l20" hover-class="rebook-btn-hover"
@click="twoPayCli" >
<text class="butText colfff">立即支付</text>
</button>
</view>
<view class="bottom-actions" v-if="[2,3,4,5].indexOf(pageData.detail.orderStatus) > -1">
<button class="cancel-btn" hover-class="cancel-btn-hover" @click="cancel">
<text class="butText">取消订单</text>
</button>
</view>
<view class="bottom-actions" v-if="pageData.detail.orderStatus == 6 && bujiao == 2">
<button class="rebook-btn" hover-class="rebook-btn-hover" @click="makeUpFor">
<text class="butText colfff">补交费用{{ bujiaoData.payStatus == 1 ? '(已支付)' : '' }}</text>
</button>
</view>
<view class="bottom-actions" v-if="[7].indexOf(pageData.detail.orderStatus) > -1">
<!-- <button class="cancel-btn" hover-class="cancel-btn-hover" @click="delOrder">
<text class="butText">删除订单</text>
</button> -->
<button class="rebook-btn " hover-class="rebook-btn-hover"
@click="route('/pagesIndex/carMap/evaluate',{orderId: orderId})"
v-if="pageData.detail.evaluateStatus == 0">
<text class="butText colfff">立即评价</text>
</button>
<button class="rebook-btn " hover-class="rebook-btn-hover"
@click="route('/pagesIndex/carMap/evaluateLook',{orderId: orderId})"
v-if="pageData.detail.evaluateStatus == 1">
<text class="butText colfff">查看评价</text>
</button>
</view>
</view>
<!-- 投诉内容 -->
<bottom-popup ref="complainPop" type="none" title="投诉信息" >
<!-- <template #title>
<text class="font36 colOrigin fontbold "
v-if="complainData.complaintStatus == 0">审核中</text>
<text class="font36 colGreen fontbold "
v-if="complainData.complaintStatus == 1">已通过</text>
<text class="font36 priceCol fontbold "
v-if="complainData.complaintStatus == 2">已拒绝</text>
</template> -->
<view class=" mar-t20 mar-l30 ">
<text class=" font28 col666">投诉原因</text>
<text class=" font28 mar-t10 mar-l30">{{complainData.complaintReason}}</text>
</view>
<view class=" mar-t20 mar-l30 ">
<text class=" font28 col666 mar-b10">具体情况</text>
<textarea class="textYuStyle font28 col333 " v-model="complainData.complaintContent"
placeholder-class="font28 col999" :maxlength="500" disabled></textarea>
</view>
<view class=" mar-t20 mar-l30 ">
<text class=" font28 col666">图片</text>
<view class="flexwrap flexrow">
<image class=" mar-r15 mar-t15 radiu12" style="width: 150rpx;height: 150rpx;"
v-for="(it,ind) in complainData.complaintPicture.split(',')" :src="it" mode="aspectFill"
@click="com.lookImg(complainData.complaintPicture.split(','),ind)"></image>
</view>
</view>
<view class="height-60"></view>
</bottom-popup>
<!-- 二次支付 -->
<bottom-popup ref="twoPay" type="none" title="支付" >
<template #title>
<text class="font36 priceCol fontbold mar-l20">{{pageData.detail.payPrice}}元</text>
</template>
<payType ref="payTypeRef" @radioChange="e => payTypeVal = e" ></payType>
<view class="bottom-actions">
<button class="rebook-btn " hover-class="rebook-btn-hover"
@click="yesTwoPayment" >
<text class="butText colfff">确认支付</text>
</button>
</view>
</bottom-popup>
<!-- 联系客服 -->
<bottom-popup ref="phonePop" type="none" title="请选择您要联系的客服">
<template #title>
<!-- <text class="col999 font28 mar-t10">我们根据选择为您提供服务</text> -->
</template>
<view class="width-750">
<view class="goPhoneIts u-flex-row "
@click="goPhone(serviceData.platformServePhone);phonePop.close()">
<image class="helpImg mar-r30" src="/static/index/help2.png" mode=""></image>
<view class="">
<text class="font44">{{serviceData.platformServePhone}}</text>
<text class="font28 col666">官方客服</text>
</view>
</view>
<view class="goPhoneIts u-flex-row "
@click="goPhone(serviceData.motorcadeServePhone);phonePop.close()"
v-if="serviceData.motorcadeServePhone">
<image class="helpImg mar-r30" src="/static/index/help1.png" mode=""></image>
<view class="">
<text class="font44">{{serviceData.motorcadeServePhone}}</text>
<text class="font28 col666">车队服务电话</text>
</view>
</view>
</view>
<view class="height-60"></view>
</bottom-popup>
<!-- 分享 -->
<sharePop ref="sharePopup" title="我正在使用舒客畅游打车" :url="`/pagesIndex/carMap/carMapOrderShare?orderId=${orderId}`"></sharePop>
<!-- 红包 -->
<redPack ref="redPackRef" :id="orderId"></redPack>
<!-- 取消订单 -->
<bottom-popup ref="cancelPop" type="none" title="取消订单">
<view style="padding: 20rpx;">
<scroll-view :scroll-y="true" style="height: 400rpx">
<u-radio-group v-model="radiovalue1" placement="column" @change="groupChange"
borderBottom>
<u-radio :customStyle="{margin: '10rpx'}"
v-for="(item, index) in radiolist1" :key="index"
:label="item.dictLabel" :name="item.dictLabel" >
</u-radio>
</u-radio-group>
</scroll-view>
<view class="bgF7 radiu8 mar-t20" style="padding: 20rpx;" v-if="radiovalue1.includes('其他')">
<textarea class="textYuStyle font28 col333 " v-model="cancelReason" placeholder="补充更详细的取消说明" :maxlength="500"
placeholder-class="font28 col999" ></textarea>
<view class="char-count">
<text class="font22 col999">{{ cancelReason.length }}/500</text>
</view>
</view>
</view>
<view class="bottom-actions">
<button class="cancel-btn" hover-class="cancel-btn-hover" @click="cancelPop.close()">
<text class="butText">不取消了</text>
</button>
<view class="width-30"></view>
<button class="rebook-btn mar-l20" hover-class="rebook-btn-hover"
@click="cancelOrder" >
<text class="butText colfff">确认</text>
</button>
</view>
</bottom-popup>
<!-- 违约金 -->
<bottom-popup ref="payPop" type="none" title="爽约费" >
<template #title>
<text class="font36 priceCol fontbold mar-l20">{{cancelData.appointmentMoney}}元</text>
</template>
<view class="mar-t30 page30">
<text class="font28 col999" v-if="cancelData.appointmentMoney">
司机已达上车点,因平台规定您需要支付爽约费
</text>
<text class="font28 col999" v-else>
本次取消无需支付爽约费
</text>
</view>
<view class="flexrow mar-t-b20 flexRight">
<text class="font36 mar-r20">退款金额</text>
<text class="font36 priceCol fontbold mar-r30">{{cancelData.refundPrice}} 元</text>
</view>
<!-- <payType ref="payTypeRef" @radioChange="e => pageData.payType = e" ></payType> -->
<view class="bottom-actions">
<button class="cancel-btn" hover-class="cancel-btn-hover" @click="payPop.close()">
<text class="butText">不取消了</text>
</button>
<view class="width-30"></view>
<button class="rebook-btn mar-l20" hover-class="rebook-btn-hover"
@click="yesCancel" >
<text class="butText colfff">确认取消</text>
</button>
</view>
</bottom-popup>
<!-- 补交费用 -->
<bottom-popup ref="buJiaoPop" type="none" title="补交费用:" >
<template #title>
<text class="font36 priceCol fontbold">
{{bujiaoData.payPrice}}元
{{ bujiaoData.payStatus == 1 ? '(已支付)' : '' }}
</text>
</template>
<view class="mar-t30 page30">
<text class="font28 " v-if="bujiaoData.backPaymentType == 1">
补交类型:更换行程
</text>
<text class="font28 " v-if="bujiaoData.backPaymentType == 2">
补交类型:包车超时
</text>
</view>
<view class="mar-t30 page30"v-if="bujiaoData.backPaymentType == 1">
<view class="flexrow">
<text class="font28 col999">出发地:</text>
<text class="font28 " >
{{bujiaoData.departAddressDetails}}
</text>
<text class="font26 col999">({{bujiaoData.departAddress}})</text>
</view>
<view class="flexrow mar-t20">
<text class="font28 col999">目的地:</text>
<text class="font28 " >
{{bujiaoData.arriveAddressDetails}}
</text>
<text class="font26 col999">({{bujiaoData.arriveAddress}})</text>
</view>
</view>
<view class="height-80" v-if="bujiaoData.payStatus == 1"></view>
<payType ref="payTypeRef" @radioChange="e => payTypeVal = e" v-if="bujiaoData.payStatus == 0"
:balance="bujiaoConfirm.balance" :credit="bujiaoConfirm.creditLimit"></payType>
<view class="bottom-actions" v-if="bujiaoData.payStatus == 0">
<button class="rebook-btn " hover-class="rebook-btn-hover"
@click="yesBujiao" >
<text class="butText colfff">确认支付</text>
</button>
</view>
</bottom-popup>
</view>
</template>
<script setup>
import { reactive, ref , onUnmounted } from 'vue'
import { onLoad , onReady , onBackPress } from '@dcloudio/uni-app'
import com from '@/utils/common'
import { route , timeFormat } from '@/uni_modules/uview-plus';
import {
accountServiceOrder_detail , dictDataByType,
accountCollection_collectionOrCancelCollection,
accountServiceOrder_orderCancel , accountServiceOrder_noPayCancel,
appointmentOrderCancel , travelVehicleOrderCancel,
accountServiceOrder_againToPay , accountServiceOrder_checkPhone,
serviceOrderComplaint_check , accountServiceOrder_payBackFee,
accountServiceOrder_payBackFeeConfirm , payBackFeePaySub,
accountServiceOrder_serviceOrderRouteLonLat
} from "@/api/nvueAPI.js"
import payment from "@/utils/payment.js"
let priceShow = ref(false)//金额明细
// 取消订单
let radiolist1 = ref([ ])
function cancelCause (){
dictDataByType({dictType: 'user_cancel_order'}).then(res=>{
radiolist1.value = res.data
})
}
let cancelReason = ref('') //传值
let radiovalue1 = ref('') //radio默认
const groupChange = (val) => {
cancelReason.value = val.includes('其他') ? '' : val
radiovalue1.value = val
}
//未支付取消订单
const noOrderCancel = () => {
accountServiceOrder_noPayCancel({ orderId: orderId.value }).then(res=>{
getdata()
if(reloadList.value){
uni.$emit('orderList',{tit:'已取消订单',it: pageData.detail})
}
})
}
// 取消弹窗
let cancelPop = ref(null)
let payPop = ref(null)
let cancelData = ref({})
const cancel = () => {
accountServiceOrder_orderCancel({orderId: orderId.value}).then(res=>{
cancelData.value = res.data
if(res.data.appointmentMoney == 0){
cancelPop.value.showDiv()
}else{
payPop.value.showDiv()
}
})
}
// 确定取消
const yesCancel = () =>{
payPop.value.close()
cancelPop.value.showDiv()
}
// 取消订单
const cancelOrder = () => {
if(pageData.detail.orderType == 1){ //已支付的订单 取消订单(此接口只适用约车的订单 orderType == 1 && (orderStatus == 2 || orderStatus == 3 || orderStatus == 4 || orderStatus == 5))
appointmentOrderCancel({
orderId: orderId.value,cancelReason: cancelReason.value
}).then(res=>{
getdata()
cancelPop.value.close()
if(reloadList.value){
uni.$emit('orderList',{tit:'已取消订单',it: pageData.detail})
}
})
}else if(pageData.detail.orderType == 3){ //已支付的订单 取消订单(此接口只适用约车的订单 orderType == 1 && (orderStatus == 2 || orderStatus == 3 || orderStatus == 4 || orderStatus == 5))
travelVehicleOrderCancel({
orderId: orderId.value,cancelReason: cancelReason.value
}).then(res=>{
getdata()
cancelPop.value.close()
if(reloadList.value){
uni.$emit('orderList',{tit:'已取消订单',it: pageData.detail})
}
})
}
}
let orderId = ref('')
let pageData = reactive({
detail:{}
})
// 地图标记点
const markers = ref([])
// 路线
const polyline = ref([])
// 收藏
let collTag = ref(0)
let complaintTag = ref(0)
// 轮询
const rollPoling = () =>{
accountServiceOrder_detail({orderId: orderId.value}).then(res=>{
collTag.value = res.data.collTag
complaintTag.value = res.data.complaintTag
//司机到起点
var startRoute = [];
if(res.data.directionDrivingResult.steps){
var start_steps = JSON.parse(res.data.directionDrivingResult.steps)
for (let i = 0; i < start_steps.length; i++) {
const poLen1 = start_steps[i].polyline.split(";");
for (let j = 0; j < poLen1.length; j++) {
console.log();
startRoute.push({
longitude: parseFloat(poLen1[j].split(",")[0]),
latitude: parseFloat(poLen1[j].split(",")[1])
});
}
}
console.log(start_steps);
}
// console.log(startRoute);
// 起点到终点
let datad = res.data.order
var points = [];
var steps = JSON.parse(datad.steps)
for (let i = 0; i < steps.length; i++) {
const poLen = steps[i].polyline.split(";");
for (let j = 0; j < poLen.length; j++) {
points.push({
longitude: parseFloat(poLen[j].split(",")[0]),
latitude: parseFloat(poLen[j].split(",")[1])
});
}
}
if([4,5,6].indexOf(res.data.order.orderStatus) > -1){
scale.value = 17.5
dqLat.value = res.data.order.driverLatitude
dqLon.value = res.data.order.driverLongitude
polyline.value = [ {
points: startRoute,
color: '#104FB9',
width: 10,
arrowLine: true,
}]
markers.value = [
{
id: 1,
longitude: Number(datad.departLongitude),
latitude: Number(datad.departLatitude),
iconPath: '/static/index/start.png',
width: 30,
height: 30,
anchor: {
x: 0.5,
y: 1
},
callout: {
content: '起点-'+(datad.departAddressDetails || datad.departAddress),
color: '#333333',
fontSize: 12,
borderRadius: 8,
bgColor: '#FFFFFF',
padding: 10,
display: 'ALWAYS',
textAlign: 'left',
borderWidth: 1,
borderColor: '#E5E5E5'
}
},
{
id: 2,
longitude: Number(datad.arriveLongitude),
latitude: Number(datad.arriveLatitude),
iconPath: '/static/index/end.png',
width: 30,
height: 30,
anchor: {
x: 0.5,
y: 1
},
callout: {
content: '终点-'+(datad.arriveAddressDetails || datad.arriveAddress),
color: '#333333',
fontSize: 12,
borderRadius: 8,
bgColor: '#FFFFFF',
padding: 10,
display: 'ALWAYS',
textAlign: 'left',
borderWidth: 1,
borderColor: '#E5E5E5'
}
},
{
id: 3,
longitude: Number(datad.driverLongitude),
latitude: Number(datad.driverLatitude),
iconPath: '/static/driverIcon.png',
width: 40,
height: 40,
anchor: {
x: 0.5,
y: 1
},
callout: {
content: res.data.directionDrivingResult.distance+'km',
color: '#333333',
fontSize: 12,
borderRadius: 8,
bgColor: '#FFFFFF',
padding: 10,
display: 'ALWAYS',
textAlign: 'left',
borderWidth: 1,
borderColor: '#E5E5E5'
}
},
]
}else{
// 完成的路线
let endRote = []
if(res.data.order.orderStatus == 7){
accountServiceOrder_serviceOrderRouteLonLat({orderId: orderId.value}).then(res=>{
const poLen2 = res.data.split(";");
for (let j = 0; j < poLen2.length; j++) {
endRote.push({
longitude: parseFloat(poLen2[j].split(",")[0]),
latitude: parseFloat(poLen2[j].split(",")[1])
});
}
console.log(endRote);
polyline.value = [{
points: endRote,
color: '#FF6B35',
width: 10,
arrowLine: true,
}]
})
}else{
polyline.value = [{
points: points,
color: '#FF6B35',
width: 10,
arrowLine: true,
}]
}
markers.value = [
{
id: 1,
longitude: Number(datad.departLongitude),
latitude: Number(datad.departLatitude),
iconPath: '/static/index/start.png',
width: 30,
height: 30,
anchor: {
x: 0.5,
y: 1
},
callout: {
content: '起点-'+(datad.departAddressDetails || datad.departAddress),
color: '#333333',
fontSize: 12,
borderRadius: 8,
bgColor: '#FFFFFF',
padding: 10,
display: 'ALWAYS',
textAlign: 'left',
borderWidth: 1,
borderColor: '#E5E5E5'
}
},
{
id: 2,
longitude: Number(datad.arriveLongitude),
latitude: Number(datad.arriveLatitude),
iconPath: '/static/index/end.png',
width: 30,
height: 30,
anchor: {
x: 0.5,
y: 1
},
callout: {
content: '终点-'+(datad.arriveAddressDetails || datad.arriveAddress),
color: '#333333',
fontSize: 12,
borderRadius: 8,
bgColor: '#FFFFFF',
padding: 10,
display: 'ALWAYS',
textAlign: 'left',
borderWidth: 1,
borderColor: '#E5E5E5'
}
},
]
}
if(res.data.routeAddressList.length > 0){
res.data.routeAddressList.forEach((el,index) =>{
markers.value.push({
id: 10 * index,
longitude: Number(el.routeAddressLon),
latitude: Number(el.routeAddressLat),
iconPath: '/static/index/tujingdian.png',
width: 12,
height: 30,
anchor: {
x: 0.5,
y: 1
},
callout: {
content: '途经点-'+el.routeAddress,
color: '#333333',
fontSize: 10,
borderRadius: 8,
bgColor: '#FFFFFF',
padding: 10,
display: 'ALWAYS',
textAlign: 'left',
borderWidth: 1,
borderColor: '#E5E5E5'
}
})
})
}
})
}
let totalPrice = ref(0)
let dqLon = ref(null)
let dqLat = ref(null)
let scale = ref(13.5)
let time = ref(null)
let butShow = ref(false)
let bujiao = ref(0)
let bujiaoData = ref({})
const getdata = () =>{
// 补交费
accountServiceOrder_payBackFee({orderId: orderId.value}).then(res=>{
bujiao.value = res.code
bujiaoData.value = res.data
})
accountServiceOrder_detail({orderId: orderId.value}).then(res=>{
// console.log(res.data.order);
pageData.detail = res.data.order
totalPrice.value = ((res.data.order.payPrice || 0) + (res.data.order.backPaymentMoney || 0)).toFixed(2)
let center = com.getCenterPoint(
{lat: res.data.order.arriveLatitude, lng: res.data.order.arriveLongitude},
{lat: res.data.order.departLatitude, lng: res.data.order.departLongitude}
)
let radiusNum = Math.abs((res.data.order.arriveLatitude - center.lat) * 100000)
console.log(radiusNum);
if(radiusNum < 3000){
scale.value = 14
}else if(radiusNum >= 3000 && radiusNum < 6000){
scale.value = 13
}else if(radiusNum >= 6000 && radiusNum < 9000){
scale.value = 12
}else if(radiusNum >= 9000 && radiusNum < 12000){
scale.value = 11
}else if(radiusNum >= 12000){
scale.value = 10
}
dqLat.value = center.lat
dqLon.value = center.lng
rollPoling()
if([3,4,5,6].indexOf(res.data.order.orderStatus) > -1){
time.value = setInterval(()=>{
rollPoling()
},5000)
butShow.value = true
}if(res.data.order.orderStatus == 7){
let newTime = new Date().getTime()
let nobutTime = new Date(res.data.order.finishLimitTime).getTime()
butShow.value = nobutTime > newTime ? true : false
}else{
clearInterval(time.value)
}
})
}
let serviceData = ref({})
let reloadList = ref(false)
onLoad((op) => {
if(op.reload){
reloadList.value = true
}
orderId.value = op.orderId
getdata()
cancelCause() //取消原因
uni.$on('payRedPack',data=>{
getdata()
})
// 客服
accountServiceOrder_checkPhone({orderId: orderId.value}).then(res=>{
serviceData.value = res.data
})
})
onUnmounted(()=>{
uni.$off('payRedPack')
clearInterval(time.value)
})
onBackPress(()=>{
clearInterval(time.value)
})
const goPhone = (e) => {
com.goPhone(e)
}
// 需要帮助
let phonePop = ref(null)
const help = () => {
phonePop.value.showDiv()
}
// 分享行程
let sharePopup = ref(null)
const shareRoute = () => {
sharePopup.value.open()
// uni.shareWithSystem({
// summary: '',
// href: 'https://uniapp.dcloud.io',
// success(){
// // 分享完成,请注意此时不一定是成功分享
// },
// fail(){
// // 分享失败
// }
// })
}
// 打赏红包
let redPackRef = ref(null)
const redPackCli = () => {
redPackRef.value.open()
}
const delOrder = () =>{
uni.showModal({
title:'确认删除此订单',
content: '删除后将无法在订单列表中查询订单,请谨慎操作',
success: (mod) => {
if(mod.confirm){
}
}
})
}
// 收藏
const collect = () => {
accountCollection_collectionOrCancelCollection({
driverId: pageData.detail.driverId
}).then(res=>{
rollPoling()
})
}
//二次支付
let twoPay = ref(null)
function twoPayCli () {
twoPay.value.showDiv()
}
let payTypeVal = ref('')
function yesTwoPayment(){
accountServiceOrder_againToPay({
orderId: orderId.value,
payType: payTypeVal.value
}).then(res=>{
if (('APP JSAPI').includes(payTypeVal.value)) {
payment.weixin(res.data, '约车二次支付',res.data.orderId)
} else if (('alipay_app').includes(payTypeVal.value)) {
payment.alipay(res.data, '约车二次支付',res.data.orderId)
}
})
}
// 投诉
let complainPop = ref(null)
let complainData = ref({})
function complainCli (){
if(complaintTag.value == 0){
uni.$u.route('/pagesIndex/carMap/complaint',{orderId: orderId.value})
}else{
serviceOrderComplaint_check({orderId: orderId.value}).then(res=>{
complainData.value = res.data
complainPop.value.showDiv()
})
}
}
// 补交费用
let buJiaoPop = ref(null)
let payTypeRef = ref(null)
let bujiaoConfirm = ref({})
function makeUpFor () {
if(bujiaoData.value.payStatus == 1){
buJiaoPop.value.showDiv()
return
}
accountServiceOrder_payBackFeeConfirm({
serviceOrderBackPaymentId: bujiaoData.value.serviceOrderBackPaymentId
}).then(res=>{
bujiaoConfirm.value = res.data
buJiaoPop.value.showDiv()
setTimeout(()=>{
if(res.data.creditLimit == 0){
payTypeRef.value.showList(0)
}else{
payTypeRef.value.showList(1)
}
},100)
})
}
function yesBujiao () {
payBackFeePaySub({
serviceOrderBackPaymentId: bujiaoData.value.serviceOrderBackPaymentId,
payType: payTypeVal.value
}).then(res=>{
if(res.code == 14){
buJiaoPop.value.close()
uni.$u.toast('支付成功')
getdata()
return
}
if (('APP JSAPI').includes(params.payType)) {
payment.weixin(res.data, '约车补交费用',res.data.orderId)
} else if (('alipay_app').includes(params.payType)) {
payment.alipay(res.data, '约车补交费用',res.data.orderId)
}
})
}
</script>
<!-- <style>
page {
background-color: #F5F5F5;
}
</style> -->
<style scoped>
@import "@/utils/nvueCommon.css";
.textYuStyle{
height: 200rpx; width: 690rpx;padding: 10rpx;
background-color: #f5f5f5;
border-radius: 12rpx;
}
.order-page {
width: 750rpx;
flex: 1;
flex-direction: column;
background-color: #F5F5F5;
}
/* 地图区域 */
.map-section {
width: 750rpx;
flex: 1;
background-color: #E5E5E5;
/* #ifndef APP */
min-height: 800rpx;
/* #endif */
}
.map {
width: 750rpx;
flex: 1;
/* #ifndef APP */
min-height: 800rpx;
/* #endif */
}
.contPart {
/* position: fixed; bottom: 0; left: 0; right: 0; */
z-index: 100;
}
/* 红色提示横幅 */
.warning-banner {
width: 750rpx;
padding-top: 20rpx;
padding-left: 30rpx;
padding-right: 30rpx;
padding-bottom: 40rpx;
background: #FF3300;
border-top-left-radius: 20rpx;
border-top-right-radius: 20rpx;
position: relative;
flex-direction: row;
align-items: center;
}
.warning-title {
font-weight: bold;
margin-right: 10rpx;
color: #FFFFFF;
font-size: 28rpx;
}
.warning-text {
font-size: 26rpx;
color: #FFFFFF;
}
.radiuDiv {
width: 750rpx;
height: 20rpx;
position: absolute;
left: 0;
bottom: 0;
border-top-left-radius: 20rpx;
border-top-right-radius: 20rpx;
background-color: #FFFFFF;
}
/* 订单状态卡片 */
.order-status-card {
width: 750rpx;
padding: 0 30rpx;
background-color: #FFFFFF;
}
.order-status-content {
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.userPerson {
padding: 30rpx;
background-color: #F7F7F7;
border-radius: 16rpx;
}
.options {
width: 68rpx;
height: 68rpx;
border-radius: 20rpx;
background: #DCE6F7;
display: flex;
align-items: center;
justify-content: center;
}
.order-status-left {
flex: 1;
flex-direction: column;
}
.order-title {
font-size: 44rpx;
font-weight: bold;
color: #000000;
margin-bottom: 20rpx;
}
.waiting-time {
font-size: 40rpx;
color: #FE5E10;
margin-bottom: 16rpx;
font-weight: 600;
}
.car-image {
width: 220rpx;
height: 160rpx;
margin-left: 30rpx;
flex-shrink: 0;
}
/* 底部按钮区域 */
.bottom-actions {
width: 750rpx;
flex-direction: row;
padding-top: 20rpx;
padding-bottom: 20rpx;
padding-left: 30rpx;
padding-right: 30rpx;
background-color: #FFFFFF;
}
.cancel-btn {
flex: 1;
height: 88rpx;
line-height: 88rpx;
text-align: center;
background-color: #F5F5F5;
border-width: 0;
padding: 0;
}
.cancel-btn {
width: 300rpx;
height: 88rpx;
line-height: 88rpx;
text-align: center;
background-color: #F5F5F5;
border-width: 0;
padding: 0;
}
.rebook-btn {
flex: 1;
height: 88rpx;
line-height: 88rpx;
text-align: center;
background-color: #104FB9;
border-width: 0;
padding: 0;
}
.butText {
font-size: 32rpx;
font-weight: bold;
}
.cancel-btn-hover {
opacity: 0.8;
background-color: #E5E5E5;
}
.rebook-btn-hover {
opacity: 0.7;
}
.opts {
width: 690rpx;
}
.optsIts {
width: 160rpx;
display: flex;
justify-content: center;
align-items: center;
}
.optsIts-img {
width: 48rpx;
height: 48rpx;
}
.optsIts-img2 {
width: 44rpx;
height: 44rpx;
margin-bottom: 4rpx;
}
.goPhoneIts {
width: 690rpx;
margin: 30rpx;
padding: 30rpx;
background: #FFFFFF;
border: 1px solid #eee;
}
.helpImg {
width: 96rpx;
height: 96rpx;
}
.dengdai {
border-bottom: 1px dashed #E0E0E0;
padding-bottom: 30rpx;
}
</style>