chuangte_bike_newxcx/page_shanghu/yunwei/xzshebei.vue

414 lines
9.2 KiB
Vue
Raw Normal View History

2025-12-20 14:29:10 +08:00
<template>
<view class="page">
2026-05-21 09:43:14 +08:00
<u-navbar title="选择订单" :border-bottom="false" :background="bgc" back-icon-color="#000" title-color="#000"
title-size="36" height="45"></u-navbar>
<view class="loading-wrap" v-if="loading && list.length === 0">
<u-loading mode="circle" size="48"></u-loading>
<text class="loading-tip">加载中...</text>
</view>
<u-empty v-else-if="!loading && list.length === 0" mode="list" text="暂无进行中的租车订单"
margin-top="120"></u-empty>
<view class="list-section" v-else>
<view class="page-tip">
<u-icon name="info-circle" size="28" color="#4C97E7"></u-icon>
<text class="page-tip-text">以下为使用中的订单点击整条卡片可切换当前主订单</text>
</view>
<scroll-view scroll-y class="list-scroll" :show-scrollbar="false">
<view hover-class="card-tap-hover" class="order-card" v-for="item in list" :key="item._key"
@click="btnitem(item)">
<view class="card-top">
<view class="card-top-left">
<text class="order-label">订单编号</text>
<text class="order-no" selectable>{{ item.orderNo }}</text>
</view>
<view class="card-action">
<text class="action-text">切换</text>
<u-icon name="arrow-right" size="28" color="#4C97E7"></u-icon>
</view>
</view>
<view class="fee-block">
<text class="fee-title">骑行费用</text>
<view class="fee-amount">
<text class="fee-num">{{ item.rideFeeText }}</text>
<text class="fee-suffix"></text>
</view>
</view>
<view class="kv-block">
<view class="kv-row">
<text class="kv-k">下单时间</text>
<text class="kv-v">{{ item.orderStartTimeText }}</text>
</view>
<view class="kv-row">
<text class="kv-k">车辆编号</text>
<text class="kv-v">{{ item.deviceSnText }}</text>
</view>
<view class="kv-row">
<text class="kv-k">车牌号</text>
<text class="kv-v">{{ item.devicePlateText }}</text>
</view>
<view class="kv-row">
<text class="kv-k">骑行时长</text>
<text class="kv-v strong">{{ item.rideDurationText }}</text>
</view>
<view class="kv-row last">
<text class="kv-k">行驶距离</text>
<text class="kv-v">{{ item.distanceKmText }}</text>
</view>
2025-12-20 14:29:10 +08:00
</view>
</view>
2026-05-21 09:43:14 +08:00
<view class="list-tail"></view>
</scroll-view>
2025-12-20 14:29:10 +08:00
</view>
</view>
</template>
<script>
export default {
data() {
return {
bgc: {
2026-05-21 09:43:14 +08:00
backgroundColor: '#fff'
2025-12-20 14:29:10 +08:00
},
list: [],
2026-05-21 09:43:14 +08:00
loading: false,
submitting: false
2025-12-20 14:29:10 +08:00
};
},
onLoad() {
2026-05-21 09:43:14 +08:00
this.getlist();
2025-12-20 14:29:10 +08:00
},
methods: {
2026-05-21 09:43:14 +08:00
mapDisplayRow(raw, index) {
const id = raw && raw.id;
const _key = id !== undefined && id !== null ? `id-${id}` : `i-${index}`;
return {
...raw,
_key,
rideFeeText: this.formatMoney(raw.rideFee),
deviceSnText: raw.deviceSn == null ? '--' : String(raw.deviceSn),
devicePlateText: raw.deviceVehicleNum == null ? '--' : String(raw.deviceVehicleNum),
orderStartTimeText: raw.orderStartTime || '--',
rideDurationText: this.calculateRideDuration(raw.orderStartTime),
distanceKmText: this.formatDistanceKm(raw.orderDistance)
};
},
formatMoney(val) {
if (val == null || val === '') return '0.00';
const n = Number(val);
return Number.isFinite(n) ? n.toFixed(2) : '0.00';
},
formatDistanceKm(meters) {
if (meters == null || meters === '') return '0.0 Km';
const m = Number(meters);
if (!Number.isFinite(m)) return '0.0 Km';
return `${(m / 1000).toFixed(1)} Km`;
2025-12-20 14:29:10 +08:00
},
2026-05-21 09:43:14 +08:00
getlist() {
this.loading = true;
this.$u
.get(`/app/orderDevice/mineUsingList`)
.then((res) => {
if (res.code == 200) {
const rows = Array.isArray(res.data) ? res.data : [];
this.list = rows.map((row, i) => this.mapDisplayRow(row, i));
} else {
this.list = [];
uni.showToast({
title: res.msg || '加载失败',
icon: 'none',
duration: 2000
});
}
})
.catch(() => {
this.list = [];
2025-12-20 14:29:10 +08:00
uni.showToast({
2026-05-21 09:43:14 +08:00
title: '网络异常,请稍后重试',
icon: 'none',
2025-12-20 14:29:10 +08:00
duration: 2000
2026-05-21 09:43:14 +08:00
});
})
.finally(() => {
this.loading = false;
});
},
btnitem(item) {
if (this.submitting) return;
this.submitting = true;
let success = false;
this.$u
.put(`/app/orderDevice/setHighestSort?id=${item.id}`)
.then((res) => {
if (res.code == 200) {
success = true;
uni.showToast({
title: '切换订单成功',
icon: 'success',
duration: 1500
});
setTimeout(() => {
uni.navigateBack();
}, 900);
} else {
uni.showToast({
title: res.msg || '操作失败',
icon: 'none',
duration: 2000
});
}
})
.catch(() => {
2025-12-20 14:29:10 +08:00
uni.showToast({
2026-05-21 09:43:14 +08:00
title: '网络异常,请稍后重试',
2025-12-20 14:29:10 +08:00
icon: 'none',
duration: 2000
2026-05-21 09:43:14 +08:00
});
})
.finally(() => {
if (!success) this.submitting = false;
});
2025-12-20 14:29:10 +08:00
},
calculateRideDuration(startTime) {
2026-05-21 09:43:14 +08:00
if (!startTime) return '--';
2025-12-20 14:29:10 +08:00
const start = new Date(startTime).getTime();
2026-05-21 09:43:14 +08:00
if (!Number.isFinite(start)) return '--';
const now = Date.now();
let diffMs = now - start;
if (!Number.isFinite(diffMs)) return '--';
if (diffMs < 0) diffMs = 0;
2025-12-20 14:29:10 +08:00
const totalMinutes = Math.max(Math.ceil(diffMs / (1000 * 60)), 1);
const hours = Math.floor(totalMinutes / 60);
const minutes = totalMinutes % 60;
return `${hours}${minutes}`;
}
2026-05-21 09:43:14 +08:00
}
2025-12-20 14:29:10 +08:00
};
</script>
<style lang="scss">
2026-05-21 09:43:14 +08:00
/* 与商户端运维模块统一:主色 #4C97E7见 yunwei/index、换电工单卡片等 */
$mc-primary: #4c97e7;
$mc-primary-soft: #ebf4ff;
$mc-primary-border: rgba(76, 151, 231, 0.22);
$page-bg: #f5f7fa;
$card-bg: #ffffff;
$text-title: #1a2332;
$text-body: #4a5568;
$text-hint: #8b95a5;
$hairline: #edf0f4;
2025-12-20 14:29:10 +08:00
2026-05-21 09:43:14 +08:00
page {
background-color: $page-bg;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
2025-12-20 14:29:10 +08:00
}
2026-05-21 09:43:14 +08:00
.page {
min-height: 100vh;
box-sizing: border-box;
display: flex;
flex-direction: column;
2025-12-20 14:29:10 +08:00
}
2026-05-21 09:43:14 +08:00
.loading-wrap {
2025-12-20 14:29:10 +08:00
display: flex;
2026-05-21 09:43:14 +08:00
flex-direction: column;
2025-12-20 14:29:10 +08:00
align-items: center;
2026-05-21 09:43:14 +08:00
justify-content: center;
padding-top: 160rpx;
flex: 1;
2025-12-20 14:29:10 +08:00
font-size: 28rpx;
}
2026-05-21 09:43:14 +08:00
.loading-tip {
margin-top: 24rpx;
color: $text-hint;
font-size: 26rpx;
}
.list-section {
flex: 1;
height: 0;
min-height: 0;
display: flex;
flex-direction: column;
box-sizing: border-box;
}
.page-tip {
flex-shrink: 0;
margin: 0 24rpx 16rpx;
padding: 18rpx 20rpx;
display: flex;
align-items: flex-start;
gap: 12rpx;
background-color: $mc-primary-soft;
border-radius: 12rpx;
border-left: 6rpx solid $mc-primary;
box-sizing: border-box;
}
.page-tip-text {
flex: 1;
padding-top: 2rpx;
font-size: 24rpx;
color: $text-body;
line-height: 1.5;
}
.list-scroll {
flex: 1;
height: 0;
box-sizing: border-box;
padding: 0 24rpx;
2025-12-20 14:29:10 +08:00
}
2026-05-21 09:43:14 +08:00
.list-tail {
height: calc(40rpx + env(safe-area-inset-bottom));
2025-12-20 14:29:10 +08:00
}
2026-05-21 09:43:14 +08:00
.order-card {
background: $card-bg;
border-radius: 16rpx;
margin-bottom: 24rpx;
overflow: hidden;
border: 1rpx solid $hairline;
box-shadow: 0 4rpx 24rpx rgba(26, 35, 50, 0.05);
}
.card-top {
2025-12-20 14:29:10 +08:00
display: flex;
2026-05-21 09:43:14 +08:00
align-items: flex-start;
2025-12-20 14:29:10 +08:00
justify-content: space-between;
2026-05-21 09:43:14 +08:00
gap: 24rpx;
padding: 24rpx 24rpx 20rpx;
}
.card-top-left {
flex: 1;
min-width: 0;
}
.order-label {
display: block;
font-size: 22rpx;
color: $text-hint;
line-height: 1.25;
2025-12-20 14:29:10 +08:00
margin-bottom: 10rpx;
}
2026-05-21 09:43:14 +08:00
.order-no {
display: block;
font-size: 30rpx;
2025-12-20 14:29:10 +08:00
font-weight: 600;
2026-05-21 09:43:14 +08:00
color: $text-title;
line-height: 1.4;
word-break: break-all;
2025-12-20 14:29:10 +08:00
}
2026-05-21 09:43:14 +08:00
.card-action {
flex-shrink: 0;
display: flex;
align-items: center;
gap: 4rpx;
align-self: center;
}
.action-text {
font-size: 26rpx;
font-weight: 500;
color: $mc-primary;
}
.fee-block {
display: flex;
align-items: center;
justify-content: space-between;
margin: 0 24rpx;
padding: 20rpx 20rpx;
background: $mc-primary-soft;
border-radius: 12rpx;
border: 1rpx solid $mc-primary-border;
2025-12-20 14:29:10 +08:00
box-sizing: border-box;
}
2026-05-21 09:43:14 +08:00
.fee-title {
font-size: 26rpx;
color: $text-body;
font-weight: 500;
}
.fee-amount {
display: flex;
align-items: baseline;
gap: 4rpx;
}
.fee-num {
font-size: 40rpx;
font-weight: 700;
color: $mc-primary;
line-height: 1;
letter-spacing: -0.5rpx;
}
.fee-suffix {
font-size: 24rpx;
color: $text-hint;
font-weight: 400;
}
.kv-block {
padding: 8rpx 24rpx 16rpx;
margin-top: 16rpx;
}
.kv-row {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 32rpx;
padding: 18rpx 0;
border-bottom: 1rpx solid $hairline;
box-sizing: border-box;
}
.kv-row.last {
border-bottom: none;
padding-bottom: 8rpx;
}
.kv-k {
flex-shrink: 0;
width: 160rpx;
font-size: 26rpx;
color: $text-hint;
line-height: 1.45;
}
.kv-v {
flex: 1;
min-width: 0;
text-align: right;
font-size: 26rpx;
color: $text-title;
line-height: 1.45;
word-break: break-all;
}
.kv-v.strong {
color: $mc-primary;
font-weight: 600;
2025-12-20 14:29:10 +08:00
}
2026-05-21 09:43:14 +08:00
.card-tap-hover {
opacity: 0.88;
background-color: #fafbfd;
2025-12-20 14:29:10 +08:00
}
2026-05-21 09:43:14 +08:00
</style>