<template>
|
<view class="order-page">
|
<view class="toolbar">
|
<view class="vehicle-filter" @click="toggleVehicleType">
|
<text class="vehicle-filter__text">{{ currentVehicleTypeLabel }}</text>
|
<image class="vehicle-filter__arrow" src="/static/icon/ar_drop@2x.png" mode="widthFix"></image>
|
</view>
|
<view class="search-box">
|
<image class="search-box__icon" src="/static/icon/ic_search@2x.png" mode="aspectFit"></image>
|
<input
|
class="search-box__input"
|
type="text"
|
v-model="keyword"
|
placeholder="搜索车辆编号/手机号"
|
placeholder-class="search-box__placeholder"
|
/>
|
</view>
|
</view>
|
|
<view class="tab-bar">
|
<view :class="activeTab === 'renting' ? 'tab-bar__item active' : 'tab-bar__item'" @click="activeTab = 'renting'">租用中</view>
|
<view :class="activeTab === 'completed' ? 'tab-bar__item active' : 'tab-bar__item'" @click="activeTab = 'completed'">已完成</view>
|
</view>
|
|
<view class="order-list">
|
<view class="order-card" v-for="item in filteredOrders" :key="item.id">
|
<view class="order-card__head">
|
<view class="order-card__code">车辆编号:{{ item.code }}</view>
|
<view class="order-card__amount" v-if="activeTab === 'completed'">{{ item.amount }}</view>
|
</view>
|
<view class="order-card__row">车辆类型:{{ item.vehicleType }}</view>
|
<view class="order-card__row">用户手机:{{ item.mobile }}</view>
|
<view class="order-card__row">骑行时间:{{ item.rideTime }}</view>
|
|
<view class="order-card__footer">
|
<view class="order-card__track" @click="handleAction('查看轨迹')">查看轨迹</view>
|
<view class="order-card__actions" v-if="activeTab === 'renting'">
|
<view class="action-btn action-btn--line" @click="handleAction('开锁')">开锁</view>
|
<view class="action-btn action-btn--line" @click="handleAction('关锁')">关锁</view>
|
<view class="action-btn action-btn--primary" @click="handleAction('强制还车')">强制还车</view>
|
</view>
|
<view class="order-card__actions" v-else>
|
<view class="action-btn action-btn--warn" @click="handleAction('退款')">退款</view>
|
</view>
|
</view>
|
</view>
|
|
<view class="empty-state" v-if="!filteredOrders.length">暂无订单数据</view>
|
</view>
|
|
<u-popup :show="showVehicleTypePopup" :round="16" mode="bottom" @close="showVehicleTypePopup = false">
|
<view class="type-popup">
|
<view class="type-popup__title">选择车辆类型</view>
|
<view
|
:class="selectedVehicleType === item.value ? 'type-popup__item active' : 'type-popup__item'"
|
v-for="item in vehicleTypeOptions"
|
:key="item.value"
|
@click="selectVehicleType(item.value)"
|
>
|
{{ item.label }}
|
</view>
|
</view>
|
</u-popup>
|
<!-- 强制还车 -->
|
<u-popup :show="show" :closeOnClickOverlay="true" mode="bottom" bgColor="#fff" :round="10" @close="show = false">
|
<view class="huanche">
|
<view class="huanche_title">强制还车</view>
|
<view class="huanche_tips">强制还车后,车辆行程结束并自动结算</view>
|
<view class="huanche_footer">
|
<view class="huanche_footer_btn line" @click="show = false">取消</view>
|
<view class="huanche_footer_btn pr">确定还车</view>
|
</view>
|
</view>
|
</u-popup>
|
<!-- 订单退款 -->
|
<u-popup :show="show1" :closeOnClickOverlay="true" mode="bottom" bgColor="#fff" :round="10" @close="show1 = false">
|
<view class="huanche">
|
<view class="huanche_title">订单退款</view>
|
<view class="huanche_info">
|
<view class="huanche_info_item">
|
<view class="label">充值金额:</view>
|
<view class="val">100元</view>
|
</view>
|
<view class="huanche_info_item">
|
<view class="label">结算金额:</view>
|
<view class="val">50元</view>
|
</view>
|
<view class="huanche_info_item">
|
<view class="label">已退金额:</view>
|
<view class="val">-</view>
|
</view>
|
<view class="huanche_info_item">
|
<view class="label">可退金额:</view>
|
<view class="val">50元</view>
|
</view>
|
</view>
|
<view class="huanche_form">
|
<view class="huanche_form_item">
|
<view class="lable"><text>*</text>退款金额(元)</view>
|
<view class="val">
|
<input type="text" placeholder="请输入退款金额" />
|
</view>
|
</view>
|
<view class="huanche_form_item">
|
<view class="lable">退款说明</view>
|
<view class="val">
|
<input type="text" placeholder="请输入退款原因" />
|
</view>
|
</view>
|
</view>
|
<view class="huanche_footer">
|
<view class="huanche_footer_btn line" @click="show1 = false">取消</view>
|
<view class="huanche_footer_btn que">确定还车</view>
|
</view>
|
</view>
|
</u-popup>
|
</view>
|
</template>
|
|
<script>
|
const rentingOrders = [
|
{
|
id: 1,
|
code: 'BH1018',
|
vehicleType: '双排四座电动代步车',
|
mobile: '180****9930',
|
rideTime: '2025-05-01 11:30:52',
|
type: 'electric'
|
},
|
{
|
id: 2,
|
code: 'BH1018',
|
vehicleType: '双排四座电动代步车',
|
mobile: '180****9930',
|
rideTime: '2025-05-01 11:30:52',
|
type: 'electric'
|
},
|
{
|
id: 3,
|
code: 'BH1018',
|
vehicleType: '双排四座电动代步车',
|
mobile: '180****9930',
|
rideTime: '2025-05-01 11:30:52',
|
type: 'electric'
|
}
|
]
|
|
const completedOrders = [
|
{
|
id: 11,
|
code: 'BH1018',
|
vehicleType: '双排四座电动代步车',
|
mobile: '180****9930',
|
rideTime: '05-01 11:30:52~05-01 12:21:11',
|
amount: '¥100.00',
|
type: 'electric'
|
},
|
{
|
id: 12,
|
code: 'BH1018',
|
vehicleType: '双排四座电动代步车',
|
mobile: '180****9930',
|
rideTime: '05-01 11:30:52~05-01 12:21:11',
|
amount: '¥100.00',
|
type: 'electric'
|
},
|
{
|
id: 13,
|
code: 'BH1018',
|
vehicleType: '双排四座电动代步车',
|
mobile: '180****9930',
|
rideTime: '05-01 11:30:52~05-01 12:21:11',
|
amount: '¥100.00',
|
type: 'electric'
|
}
|
]
|
|
export default {
|
data() {
|
return {
|
show: false,
|
show1: false,
|
activeTab: 'renting',
|
keyword: '',
|
selectedVehicleType: '',
|
showVehicleTypePopup: false,
|
vehicleTypeOptions: [
|
{ label: '车辆类型', value: '' },
|
{ label: '双排四座电动代步车', value: 'electric' },
|
{ label: '普通自行车', value: 'bike' }
|
],
|
rentingOrders,
|
completedOrders
|
}
|
},
|
computed: {
|
currentVehicleTypeLabel() {
|
const current = this.vehicleTypeOptions.find(item => item.value === this.selectedVehicleType)
|
return current ? current.label : '车辆类型'
|
},
|
filteredOrders() {
|
const source = this.activeTab === 'renting' ? this.rentingOrders : this.completedOrders
|
const keyword = this.keyword.trim().toLowerCase()
|
|
return source.filter(item => {
|
const matchType = !this.selectedVehicleType || item.type === this.selectedVehicleType
|
const searchText = `${item.code}${item.mobile}`.toLowerCase()
|
const matchKeyword = !keyword || searchText.includes(keyword)
|
return matchType && matchKeyword
|
})
|
}
|
},
|
methods: {
|
toggleVehicleType() {
|
this.showVehicleTypePopup = true
|
},
|
selectVehicleType(value) {
|
this.selectedVehicleType = value
|
this.showVehicleTypePopup = false
|
},
|
handleAction(text) {
|
if (text === '强制还车') {
|
this.show = true
|
} else if (text === '退款') {
|
this.show1 = true
|
}
|
// uni.showToast({
|
// title: `${text}功能待接入`,
|
// icon: 'none'
|
// })
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
page {
|
background: #f7f7f7;
|
}
|
|
.order-page {
|
min-height: 100vh;
|
background: #f7f7f7;
|
}
|
|
.huanche {
|
width: 100%;
|
padding: 0 20rpx;
|
box-sizing: border-box;
|
.huanche_title {
|
font-weight: 500;
|
font-size: 32rpx;
|
color: #222222;
|
margin-top: 40rpx;
|
text-align: center;
|
}
|
.huanche_tips {
|
width: 100%;
|
font-weight: 400;
|
font-size: 30rpx;
|
color: #333333;
|
text-align: center;
|
margin-top: 76rpx;
|
}
|
.huanche_info {
|
width: 100%;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
flex-wrap: wrap;
|
margin-top: 30rpx;
|
.huanche_info_item {
|
width: 50%;
|
display: flex;
|
align-items: center;
|
margin-bottom: 20rpx;
|
.label {
|
font-weight: 400;
|
font-size: 28rpx;
|
color: #666666;
|
}
|
.val {
|
font-weight: 400;
|
font-size: 28rpx;
|
color: #222222;
|
}
|
}
|
}
|
.huanche_form {
|
width: 100%;
|
margin-top: 20rpx;
|
display: flex;
|
flex-direction: column;
|
.huanche_form_item {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
margin-bottom: 30rpx;
|
&:last-child {
|
margin: 0 !important;
|
}
|
.lable {
|
flex-shrink: 0;
|
font-weight: 600;
|
font-size: 30rpx;
|
color: #222222;
|
text {
|
color: #FF5A31;
|
}
|
}
|
.val {
|
width: 468rpx;
|
height: 98rpx;
|
background: #F8F9FB;
|
border-radius: 140rpx;
|
border: 1rpx solid #E5E5E5;
|
padding: 0 32rpx;
|
box-sizing: border-box;
|
input {
|
width: 100%;
|
height: 100%;
|
font-weight: 400;
|
font-size: 30rpx;
|
color: #222222;
|
text-align: right;
|
}
|
}
|
}
|
}
|
.huanche_footer {
|
width: 100%;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
margin-top: 94rpx;
|
.huanche_footer_btn {
|
width: 344rpx;
|
height: 96rpx;
|
line-height: 96rpx;
|
text-align: center;
|
border-radius: 46rpx;
|
}
|
.line {
|
border: 1rpx solid #01B6AD;
|
font-weight: 500;
|
font-size: 32rpx;
|
color: #01B6AD;
|
background-color: #ffffff;
|
}
|
.pr {
|
background: #01B6AD;
|
font-weight: 500;
|
font-size: 32rpx;
|
color: #FFFFFF;
|
}
|
.que {
|
background: #FF5A31;
|
font-weight: 500;
|
font-size: 32rpx;
|
color: #FFFFFF;
|
}
|
}
|
}
|
|
.toolbar {
|
padding: 18rpx 20rpx 16rpx;
|
display: flex;
|
align-items: center;
|
background: #ffffff;
|
}
|
|
.vehicle-filter {
|
width: 184rpx;
|
height: 72rpx;
|
border-radius: 31rpx;
|
background: #f7f7f7;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
flex-shrink: 0;
|
}
|
|
.vehicle-filter__text {
|
line-height: 40rpx;
|
font-weight: 400;
|
font-size: 26rpx;
|
color: #333333;
|
}
|
|
.vehicle-filter__arrow {
|
flex-shrink: 0;
|
width: 20rpx;
|
margin-left: 12rpx;
|
}
|
|
.search-box {
|
flex: 1;
|
height: 72rpx;
|
margin-left: 14rpx;
|
padding: 0 24rpx;
|
border-radius: 31rpx;
|
background: #f7f7f7;
|
display: flex;
|
align-items: center;
|
}
|
|
.search-box__icon {
|
width: 28rpx;
|
height: 28rpx;
|
flex-shrink: 0;
|
}
|
|
.search-box__input {
|
flex: 1;
|
height: 72rpx;
|
margin-left: 16rpx;
|
font-size: 26rpx;
|
color: #333333;
|
}
|
|
.search-box__placeholder {
|
color: #b7b7b7;
|
font-size: 28rpx;
|
}
|
|
.tab-bar {
|
height: 82rpx;
|
padding: 0 96rpx;
|
background: #ffffff;
|
display: flex;
|
align-items: flex-end;
|
justify-content: space-between;
|
}
|
|
.tab-bar__item {
|
position: relative;
|
padding-bottom: 12rpx;
|
font-weight: 400;
|
font-size: 30rpx;
|
color: #666666;
|
line-height: 54rpx;
|
}
|
|
.tab-bar__item.active {
|
color: #01B6AD;
|
font-weight: 600;
|
}
|
|
.tab-bar__item.active::after {
|
content: '';
|
position: absolute;
|
left: 50%;
|
bottom: 0;
|
width: 108rpx;
|
height: 4rpx;
|
background: #01B6AD;
|
border-radius: 4rpx;
|
transform: translateX(-50%);
|
}
|
|
.order-list {
|
padding: 20rpx;
|
box-sizing: border-box;
|
}
|
|
.order-card {
|
margin-top: 16rpx;
|
padding: 22rpx 24rpx 0;
|
background: #ffffff;
|
border-radius: 24rpx;
|
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.03);
|
overflow: hidden;
|
&:first-child {
|
margin: 0 !important;
|
}
|
}
|
|
.order-card__head {
|
display: flex;
|
align-items: flex-start;
|
justify-content: space-between;
|
}
|
|
.order-card__code {
|
font-weight: 600;
|
font-size: 32rpx;
|
color: #222222;
|
line-height: 58rpx;
|
}
|
|
.order-card__amount {
|
font-weight: 600;
|
font-size: 28rpx;
|
color: #FF5A31;
|
line-height: 50rpx;
|
flex-shrink: 0;
|
}
|
|
.order-card__row {
|
font-weight: 400;
|
font-size: 26rpx;
|
color: #666666;
|
line-height: 44rpx;
|
}
|
|
.order-card__footer {
|
margin-top: 22rpx;
|
padding: 18rpx 0 20rpx;
|
border-top: 2rpx solid #f1f1f1;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
}
|
|
.order-card__track {
|
font-weight: 400;
|
font-size: 26rpx;
|
color: #01B6AD;
|
line-height: 44rpx;
|
}
|
|
.order-card__actions {
|
display: flex;
|
align-items: center;
|
}
|
|
.action-btn {
|
min-width: 120rpx;
|
height: 68rpx;
|
padding: 0 32rpx;
|
margin-left: 20rpx;
|
border-radius: 34rpx;
|
font-size: 28rpx;
|
line-height: 68rpx;
|
text-align: center;
|
box-sizing: border-box;
|
}
|
|
.action-btn--line {
|
border: 2rpx solid #01B6AD;
|
color: #01B6AD;
|
background: #ffffff;
|
}
|
|
.action-btn--primary {
|
background: #01B6AD;
|
color: #ffffff;
|
}
|
|
.action-btn--warn {
|
border: 2rpx solid #FF5A31;
|
color: #FF5A31;
|
background: #ffffff;
|
}
|
|
.empty-state {
|
padding: 120rpx 0;
|
font-size: 28rpx;
|
line-height: 40rpx;
|
text-align: center;
|
color: #999999;
|
}
|
|
.type-popup {
|
padding: 32rpx 24rpx 40rpx;
|
background: #ffffff;
|
}
|
|
.type-popup__title {
|
font-size: 32rpx;
|
font-weight: 600;
|
line-height: 44rpx;
|
text-align: center;
|
color: #222222;
|
}
|
|
.type-popup__item {
|
height: 88rpx;
|
margin-top: 20rpx;
|
border-radius: 16rpx;
|
background: #f7f7f7;
|
font-size: 30rpx;
|
line-height: 88rpx;
|
text-align: center;
|
color: #666666;
|
}
|
|
.type-popup__item.active {
|
background: rgba(1, 182, 173, 0.12);
|
color: #01b6ad;
|
font-weight: 600;
|
}
|
</style>
|