2025-05-16 16:52:21 +08:00

674 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<map id="mapRef" ref="mapRef" style="width: 100%;height: 100vh;" show-location :longitude="location.longitude"
:latitude="location.latitude" :markers="markers" :scale="scale" :polygons="polygons" :polyline="polylines"
:circles="circles" @markertap="openBikeInfo" />
<div v-if="showTools" class="divMapTools" style="left: 10px;">
<div>
<image class="divImg" :src='imgPath+"static/userui/home/localtion.png"' @click="refresh" />
</div>
<div>
<image class="divImg" :src='imgPath+"static/userui/home/fault.png"' @click="reportFault" />
</div>
</div>
<div v-if="showTools" class="divMapTools" style="right: 10px;">
<div>
<image class="divImg" :src='imgPath+"static/userui/home/packing.png"' @click="applySite" />
</div>
<div>
<image class="divImg" :src='imgPath+"static/userui/home/mine.png"' @click="getMine" />
</div>
</div>
<div v-if="hasOrder" class="divMapOrder" @click="openOrderPay">
<div>
<image style="width: 15px;height: 15px;margin-left: 15px;margin-right: 10px;"
:src='imgPath+"static/userui/home/speaker.png"' />
<label>有骑行订单未支付,请查看</label>
</div>
<div style="margin-right: 15px;">
<label>查看 <label>></label></label>
</div>
</div>
<div class="divMapBottom">
<div :class="(hasOrder?'divScanBtnDis ':'')+'divScanBtn'" @click="scanBike">
<uni-icons type="scan" color="white" :size="25"></uni-icons>
<label style="margin-left: 5px;">扫码用车</label>
</div>
</div>
<div v-if="showOrder" class="divOrder">
<div class="divOrderRow">
<div class="divOrderCell">
<image class="divOrderImg" :src='imgPath+"static/userui/home/money.png"' />
<label>费用</label>
<label>{{order.money}}</label>
</div>
<div class="divOrderCell2">
<label>{{order.bikecode}}</label>
</div>
</div>
<div class="divOrderRow" style="font-size: 12px;">
<div class="divOrderCell">
<image class="divOrderImg" :src='imgPath+"static/userui/home/timer.png"' />
<label>计时</label>
<label style="color: #61D246;">{{order.time}}</label>
</div>
<!-- <div class="divOrderCell2">
<image class="divOrderImg" :src='imgPath+"static/userui/home/bike.png"' />
<label>骑行</label>
<label style="color: #61D246;">{{order.mileage}}</label>
</div> -->
</div>
<div class="divOderBtn">
<image v-if="orderState==0" style="width: 120px;height: 40px;" :src='imgPath+"static/userui/home/lock.png"'
@click="lockRiding" />
<image v-if="orderState==1" style="width: 120px;height: 40px;" :src=' imgPath+"static/userui/home/run.png"'
@click="continueRiding" />
<image style="width: 160px;height: 40px;" :src='imgPath+"static/userui/home/endride.png"'
@click="endRiding" />
</div>
</div>
<div v-if="showMess!=1" class="divMess">
<uni-card>
<uni-list border>
<uni-list-item :thumb='imgPath+"static/userui/home/map1.png"' thumb-size="lg">
<template v-slot:body>
<div class="divMessTitle1">服务区域</div>
<div class="divMessTitle2">请在服务区域内骑行</div>
</template>
</uni-list-item>
<uni-list-item :thumb='imgPath+"static/userui/home/map2.png"' thumb-size="lg">
<template v-slot:body>
<div class="divMessTitle1">换车区域</div>
<div class="divMessTitle2">还车时确保车辆已经到达还车区域或者距你最近的停车网点</div>
</template>
</uni-list-item>
<uni-list-item :thumb='imgPath+"static/userui/home/map3.png"' thumb-size="lg">
<template v-slot:body>
<div class="divMessTitle1">停车网点</div>
<div class="divMessTitle2">还车至停车网点时长费最多可半价优惠</div>
</template>
</uni-list-item>
</uni-list>
<div class="divMessWorn">
<div class="divMessWornTitle">
·注意事项
</div>
<div class="divMessWornContent">禁止私自加锁或破坏车辆</div>
<div class="divMessWornContent">未满12岁禁止骑行</div>
<div class="divMessWornContent">如车辆故障及时通过app保修</div>
</div>
<div class="divMessBtn">
<label
style="color: #61D145;border: 1px solid #0000000f;padding: 5px 15px;border-radius: 5px;box-shadow: 2px 2px #0000000a;"
@click="clickMess">已知晓</label>
</div>
</uni-card>
</div>
<div v-if="showBikeInfo" style="position: absolute;z-index: 2000;bottom: 0;width: 100vw;">
<bike-info :bikedata="bikeData" @close="closeBikeInfo" />
</div>
<div v-if="showOrderPay" style="position: absolute;z-index: 2000;bottom: 0;width: 100vw;">
<bike-pay :orderId="orderData.orderId" />
</div>
</template>
<script setup>
import {
ref,
onMounted,
getCurrentInstance
} from 'vue';
import {
showModelMessage,
getUrlParams,
jkcBaseDecode
} from "@/utils/tools.js";
import {
callOrdereApi,
callOperateApi
} from "@/utils/api.js";
import {
findIndex
} from 'lodash';
import config from '@/utils/config';
import {
onShow,
onUnload
} from "@dcloudio/uni-app";
import * as map from "@/utils/usermap.js";
const imgPath = config.imgPath;
const location = ref({
longitude: "",
latitude: ""
});
const scale = ref(15);
const markers = ref([]);
const polygons = ref([]); //面
const polylines = ref([]); //线
const circles = ref([]); //圆
const pointStart = 100000000000;
const pointEnd = 100000000001;
let oMap = null;
const showTools = ref(true);
let oUser = null;
const showMess = ref(uni.getStorageSync("kbike-mess"));
const hasOrder = ref(false); //是否有订单
const showOrder = ref(false);
const order = ref({
bikecode: "123456",
money: "2.5",
time: "22.58min",
mileage: "5.6km"
});
//订单信息
let orderData = {
bikeCode: null,
status: null,
createdAt: null,
orderId: null
};
let orderTimer = null;
const orderState = ref(0);
const showOrderPay = ref(false);
//车辆
let arrBikeData = [];
const showBikeInfo = ref(false);
const bikeData = ref({});
//加载数据
function getLoalcationData() {
map.getLoalcation(res => {
const {
latitude,
longitude
} = res;
location.value = {
latitude,
longitude
};
oMap.moveToLocation({})
const params = {
latitude,
longitude,
radius: 20
};
callOrdereApi("userOrders/bikeList", params, "post").then(res => {
console.log("11111111111111111", "userOrders/bikeList", res);
const {
code,
data,
message
} = res;
if (code != 200) {
showModelMessage(message);
return;
}
arrBikeData = data || [];
const arrData = markers.value || [];
arrBikeData.map((item, index) => {
const {
longitude,
latitude
} = item;
arrData.push(map.addMarker(index, longitude, latitude, "mapbike.png",
true));
})
markers.value = arrData;
});
})
// uni.getLocation({
// type: 'gcj02',
// geocode: true,
// success(res) {
// location.value = {
// latitude,
// longitude
// };
// },
// fail(res) {
// }
// });
}
function clickMess() {
uni.setStorageSync("kbike-mess", 1);
showMess.value = 1;
}
//刷新
function refresh() {
getLoalcationData();
}
//故障上报
function reportFault() {
if (!oUser) {
tologin();
return;
}
uni.navigateTo({
url: "/pages/user/login/TroubleReportUser"
})
}
//申请站点
function applySite() {
if (!oUser) {
tologin();
return;
}
uni.navigateTo({
url: "/pages/user/scan/applysite"
})
}
//个人中心
function getMine() {
if (!oUser) {
tologin();
return;
}
uni.navigateTo({
url: "/pages/user/mine/MePage"
})
}
//扫描
function scanBike() {
if (!oUser) {
tologin();
return;
}
const {
userId
} = oUser;
uni.navigateTo({
url: "/pages/user/scan/scancode?type=ride"
})
}
//显示订单
function openOrderPay() {
showTools.value = false;
showOrderPay.value = true;
}
//获取订单
function getOrder() {
const {
userId
} = oUser;
callOrdereApi("userOrders/checkHistoryOrder", {
userId
}, "get").then(res => {
console.log("111111111111111", "userOrders/checkHistoryOrder", res);
const {
code,
data,
message
} = res;
if (code != 200) {
showModelMessage(message);
return;
}
if (!data) { //订单完成
completeRiding();
return;
}
const {
bikeCode,
status,
createdAt,
orderId,
tempLock,
ridePoint,
returnPoint,
endTime
} = data;
//0-进行中 1-已取消 2-待支付 3-已支付 4-退款中 5-已退款
orderState.value = tempLock ? 1 : 0;
orderData = data;
if (status == 2) {
completeRiding();
hasOrder.value = true;
getTracking();
return;
} else if (status != 0) {
completeRiding();
return;
}
showOrder.value = true;
if (status == 0) {
// 获取订单信息
getOrderInfo(bikeCode);
order.value.bikecode = bikeCode;
// 设置 intervalId 变量来保存定时器 ID
const intervalId = setInterval(() => {
// 更新订单时间
order.value.time = timeDifference(createdAt);
console.log(order.value.time); // 输出更新时间
if (!showOrder.value) { // 如果 showOrder 为 false停止轮询
clearInterval(intervalId); // 使用 intervalId 来停止轮询
}
}, 1000);
}
if (tempLock == 1) {
getTracking();
return;
}
getTracking();
// if (!orderTimer) {
// orderTimer = setInterval(getTracking, 100000);
// }
})
}
const getOrderInfo = (bikeCode) => {
const params = {
"userId": oUser.userId,
"bikeCode": bikeCode
}
callOrdereApi("userOrders/costCalculation", params).then(res => {
if (res.code == 200) {
order.value.money = res.data;
}
})
}
//轨迹
function getTracking() {
const {
bikeCode,
createdAt,
ridePoint,
returnPoint,
endTime
} = orderData;
let params = {
ebikeCode: bikeCode,
startTime: createdAt
}
if (endTime) params = {
...params,
endTime
}
console.log("7777777777777", params);
callOperateApi("ebikeTracking/query", params, "post").then(res => {
console.log("7777777777777", "ebikeTracking/query", res);
const {
code,
data,
message
} = res;
if (code != 200) {
return;
}
const arrPoints = (!data || data.length == 0) ? [] : data.map(item => {
const {
lngGCJ02,
latGCJ02
} = item;
return {
longitude: lngGCJ02,
latitude: latGCJ02
}
});
const startPoint = ridePoint.split(",");
const lng = startPoint[0];
const lat = startPoint[1];
const start = {
longitude: lng,
latitude: lat
}
const arrMakers = markers.value || [];
arrPoints.splice(0, 0, start);
let indexStart = findIndex(arrMakers, {
pointStart
});
indexStart = indexStart == -1 ? arrMakers.length : indexStart;
arrMakers[indexStart] = map.addMarker(pointStart, lng, lat, "start.png");
if (data && data.length > 0) {
let {
lngGCJ02: endlng,
latGCJ02: endlat
} = data[data.length - 1];
arrMakers[indexStart + 1] = map.addMarker(pointEnd, endlng, endlat, "end.png");
}
markers.value = arrMakers;
if (arrPoints.length > 1) {
polylines.value = [map.addLine("#168DED", arrPoints)];
}
})
}
//完成骑行
function completeRiding() {
if (!orderTimer) return;
clearInterval(orderTimer);
orderTimer = null;
showOrder.value = false;
hasOrder.value = false;
orderState.value = 0;
}
function tologin() {
uni.navigateTo({
url: "/pages/user/login/wx_login"
})
}
//临时锁车
function lockRiding() {
const {
userId
} = oUser;
const {
bikeCode
} = orderData;
const params = {
userId,
bikeCode
}
callOrdereApi("userOrders/tempLock", params, "post").then(res => {
const {
code,
message,
data
} = res;
showModelMessage(message)
if (code == 200) {
if (orderTimer) {
clearInterval(orderTimer);
orderTimer = null;
}
orderState.value = 1;
}
});
}
//结束用车
function endRiding() {
checkBikeEnding();
}
function checkBikeEnding(callback) {
const {
bikeCode
} = orderData;
const params = {
bikeCode
}
//运营区和停车区检查
const arrMethod = [callOrdereApi("userOrders/checkBikeInOperation", params, "get"), callOrdereApi(
"userOrders/checkBikeInParking", params, "get")]
Promise.all(arrMethod).then(([res1, res2]) => {
if (res1.code != 200) {
showModelMessage(res1.message);
return;
}
if (res2.code != 200) {
showModelMessage(res2.message);
return;
}
doneRide();
});
}
//完成骑行
function doneRide() {
const {
userId
} = oUser;
const {
bikeCode
} = orderData;
const params = {
userId,
bikeCode
}
callOrdereApi("userOrders/doneRide", params, "post").then(res => {
const {
code,
data,
message
} = res;
if (code != 200) {
showModelMessage(message);
return;
}
completeRiding();
openOrderPay();
})
}
//继续骑行 需要开锁
function continueRiding() {
const {
userId
} = oUser;
const {
bikeCode
} = orderData;
const params = {
userId,
bikeCode
}
callOrdereApi("userOrders/continueCycling", params, "post").then(res => {
const {
code,
message,
data
} = res;
showModelMessage(message)
if (code == 200) {
if (orderTimer) {
clearInterval(orderTimer);
orderTimer = null;
}
orderState.value = 0;
}
});
//getOrder();
}
//查看车辆信息
function openBikeInfo(e) {
if (!oUser) {
tologin();
return;
}
const {
markerId
} = e.detail;
if (markerId == pointEnd || markerId == pointStart) {
return;
}
bikeData.value = arrBikeData[markerId];
showBikeInfo.value = true;
showTools.value = false;
showOrderPay.value = false;
}
//关闭车辆信息
function closeBikeInfo() {
showBikeInfo.value = false;
showTools.value = true;
}
onMounted(() => {
const instance = getCurrentInstance();
oMap = uni.createMapContext("mapRef", {
this: instance.proxy
});
getLoalcationData();
})
onShow(() => {
if (uni.getStorageSync("wechat_user")) {
oUser = JSON.parse(jkcBaseDecode(uni.getStorageSync("wechat_user")));
}
const {
userId
} = oUser;
if (userId) {
getOrder();
}
});
onUnload(() => {
console.log("9999999999999999999", "onUnload", orderTimer);
})
function parseDate(createTime) {
// 将日期字符串转换为 iOS 支持的格式
createTime = createTime.replace(" ", "T"); // 将空格替换为 "T",使其符合 "yyyy-MM-ddTHH:mm:ss" 格式
return new Date(createTime); // 返回新的 Date 对象
}
function timeDifference(createTime) {
const currentTime = new Date();
const createDate = parseDate(createTime); // 使用转换后的日期字符串
const diffInSeconds = Math.floor((currentTime - createDate) / 1000);
if (diffInSeconds < 60) return `${diffInSeconds}`;
const diffInMinutes = Math.floor(diffInSeconds / 60);
if (diffInMinutes < 60) {
const remainingSeconds = diffInSeconds % 60;
return `${diffInMinutes}分钟 ${remainingSeconds}`;
}
const diffInHours = Math.floor(diffInMinutes / 60);
if (diffInHours < 24) {
const remainingMinutes = diffInMinutes % 60;
const remainingSeconds = diffInSeconds % 60;
return `${diffInHours}小时 ${remainingMinutes}分钟 ${remainingSeconds}`;
}
const diffInDays = Math.floor(diffInHours / 24);
return `${diffInDays}${diffInHours % 24}小时 ${diffInMinutes % 60}分钟 ${diffInSeconds % 60}`;
}
</script>
<style scoped>
@import url("home.css");
</style>