From f82526f5b34a023e11310adba11cae555adc40cb Mon Sep 17 00:00:00 2001
From: MrShi <1878285526@qq.com>
Date: 星期三, 01 七月 2026 18:15:01 +0800
Subject: [PATCH] 页面

---
 bicycle/pages/order/order.vue |  438 +++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 331 insertions(+), 107 deletions(-)

diff --git a/bicycle/pages/order/order.vue b/bicycle/pages/order/order.vue
index 02fed67..9caf101 100644
--- a/bicycle/pages/order/order.vue
+++ b/bicycle/pages/order/order.vue
@@ -11,8 +11,10 @@
 					class="search-box__input"
 					type="text"
 					v-model="keyword"
-					placeholder="鎼滅储杞﹁締缂栧彿/鎵嬫満鍙�"
+					placeholder="鎼滅储鐢ㄦ埛鎵嬫満鍙�"
 					placeholder-class="search-box__placeholder"
+					confirm-type="search"
+					@confirm="handleSearch"
 				/>
 			</view>
 		</view>
@@ -23,29 +25,34 @@
 		</view>
 
 		<view class="order-list">
-			<view class="order-card" v-for="item in filteredOrders" :key="item.id">
+			<view class="order-card" v-for="item in list" :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 class="order-card__code">璁㈠崟缂栧彿锛歿{ item.code || '-' }}</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__row">杞﹁締缂栧彿锛歿{ item.bikeCode || '-' }}</view>
+				<view class="order-card__row">璁㈠崟绫诲瀷锛歿{ item.bikeTypeText }}</view>
+				<view class="order-card__row">缁撶畻杞﹀瀷锛歿{ item.paramName || '-' }}</view>
+				<view class="order-card__row">鐢ㄦ埛鎵嬫満锛歿{ item.phone || '-' }}</view>
+				<view class="order-card__row">楠戣寮�濮嬫椂闂达細{{ item.rentDate || '-' }}</view>
+				<view v-if="activeTab === 'completed'" class="order-card__row">缁撶畻鏃堕棿锛歿{ item.closeDate || '-' }}</view>
 
 				<view class="order-card__footer">
-					<view class="order-card__track" @click="handleAction('鏌ョ湅杞ㄨ抗')">鏌ョ湅杞ㄨ抗</view>
+					<view v-if="Number(item.bikeType) === 1" class="order-card__track" @click="handleAction('鏌ョ湅杞ㄨ抗', item)">鏌ョ湅杞ㄨ抗</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 v-if="Number(item.bikeType) === 1" class="action-btn action-btn--line" @click="handleAction('寮�閿�', item)">寮�閿�</view>
+						<view v-if="Number(item.bikeType) === 1" class="action-btn action-btn--line" @click="handleAction('鍏抽攣', item)">鍏抽攣</view>
+						<view class="action-btn action-btn--primary" @click="handleAction('寮哄埗杩樿溅', item)">寮哄埗杩樿溅</view>
 					</view>
 					<view class="order-card__actions" v-else>
-						<view class="action-btn action-btn--warn" @click="handleAction('閫�娆�')">閫�娆�</view>
+						<view class="action-btn action-btn--warn" @click="handleAction('閫�娆�', item)">閫�娆�</view>
 					</view>
 				</view>
 			</view>
 
-			<view class="empty-state" v-if="!filteredOrders.length">鏆傛棤璁㈠崟鏁版嵁</view>
+			<view class="empty-state" v-if="!list.length && !loading">鏆傛棤璁㈠崟鏁版嵁</view>
+			<view class="load-more-tip" v-if="list.length">
+				{{ loading ? '鍔犺浇涓�...' : (finished ? '娌℃湁鏇村浜�' : '涓婃媺鍔犺浇鏇村') }}
+			</view>
 		</view>
 
 		<u-popup :show="showVehicleTypePopup" :round="16" mode="bottom" @close="showVehicleTypePopup = false">
@@ -68,49 +75,49 @@
 				<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 class="huanche_footer_btn pr" @click="confirmForceBack">纭畾杩樿溅</view>
 				</view>
 			</view>
 		</u-popup>
 		<!-- 璁㈠崟閫�娆� -->
-		<u-popup :show="show1" :closeOnClickOverlay="true" mode="bottom" bgColor="#fff" :round="10" @close="show1 = false">
+		<u-popup :show="show1" :closeOnClickOverlay="true" mode="bottom" bgColor="#fff" :round="10" @close="closeRefundPopup">
 			<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 class="val">{{ formatMoneyText(refundInfo.goodsorderMoney) }}</view>
 					</view>
 					<view class="huanche_info_item">
 						<view class="label">缁撶畻閲戦锛�</view>
-						<view class="val">50鍏�</view>
+						<view class="val">{{ formatMoneyText(refundInfo.closeMoney) }}</view>
 					</view>
 					<view class="huanche_info_item">
 						<view class="label">宸查��閲戦锛�</view>
-						<view class="val">-</view>
+						<view class="val">{{ formatMoneyText(refundInfo.hasRefundMoney) }}</view>
 					</view>
 					<view class="huanche_info_item">
 						<view class="label">鍙��閲戦锛�</view>
-						<view class="val">50鍏�</view>
+						<view class="val">{{ formatMoneyText(refundInfo.canBanlanceMoney) }}</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="璇疯緭鍏ラ��娆鹃噾棰�" />
+							<input v-model="refundForm.money" type="digit" placeholder="璇疯緭鍏ラ��娆鹃噾棰�" />
 						</view>
 					</view>
 					<view class="huanche_form_item">
 						<view class="lable">閫�娆捐鏄�</view>
 						<view class="val">
-							<input type="text" placeholder="璇疯緭鍏ラ��娆惧師鍥�" />
+							<input v-model="refundForm.reason" 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 class="huanche_footer_btn line" @click="closeRefundPopup">鍙栨秷</view>
+					<view class="huanche_footer_btn que" @click="confirmRefund">纭閫�娆�</view>
 				</view>
 			</view>
 		</u-popup>
@@ -118,63 +125,6 @@
 </template>
 
 <script>
-	const rentingOrders = [
-		{
-			id: 1,
-			code: 'BH1018',
-			vehicleType: '鍙屾帓鍥涘骇鐢靛姩浠f杞�',
-			mobile: '180****9930',
-			rideTime: '2025-05-01 11:30:52',
-			type: 'electric'
-		},
-		{
-			id: 2,
-			code: 'BH1018',
-			vehicleType: '鍙屾帓鍥涘骇鐢靛姩浠f杞�',
-			mobile: '180****9930',
-			rideTime: '2025-05-01 11:30:52',
-			type: 'electric'
-		},
-		{
-			id: 3,
-			code: 'BH1018',
-			vehicleType: '鍙屾帓鍥涘骇鐢靛姩浠f杞�',
-			mobile: '180****9930',
-			rideTime: '2025-05-01 11:30:52',
-			type: 'electric'
-		}
-	]
-
-	const completedOrders = [
-		{
-			id: 11,
-			code: 'BH1018',
-			vehicleType: '鍙屾帓鍥涘骇鐢靛姩浠f杞�',
-			mobile: '180****9930',
-			rideTime: '05-01 11:30:52~05-01 12:21:11',
-			amount: '楼100.00',
-			type: 'electric'
-		},
-		{
-			id: 12,
-			code: 'BH1018',
-			vehicleType: '鍙屾帓鍥涘骇鐢靛姩浠f杞�',
-			mobile: '180****9930',
-			rideTime: '05-01 11:30:52~05-01 12:21:11',
-			amount: '楼100.00',
-			type: 'electric'
-		},
-		{
-			id: 13,
-			code: 'BH1018',
-			vehicleType: '鍙屾帓鍥涘骇鐢靛姩浠f杞�',
-			mobile: '180****9930',
-			rideTime: '05-01 11:30:52~05-01 12:21:11',
-			amount: '楼100.00',
-			type: 'electric'
-		}
-	]
-
 	export default {
 		data() {
 			return {
@@ -183,34 +133,71 @@
 				activeTab: 'renting',
 				keyword: '',
 				selectedVehicleType: '',
+				page: 1,
+				list: [],
+				loading: false,
+				finished: false,
+				updatingLock: false,
+				forceBackLoading: false,
+				refundLoading: false,
+				currentOrderId: '',
+				refundOrderId: '',
+				refundInfo: {
+					canBanlanceMoney: '',
+					closeMoney: '',
+					goodsorderMoney: '',
+					hasRefundMoney: ''
+				},
+				refundForm: {
+					money: '',
+					reason: ''
+				},
+				searchTimer: null,
 				showVehicleTypePopup: false,
 				vehicleTypeOptions: [
-					{ label: '杞﹁締绫诲瀷', value: '' },
-					{ label: '鍙屾帓鍥涘骇鐢靛姩浠f杞�', value: 'electric' },
-					{ label: '鏅�氳嚜琛岃溅', value: 'bike' }
-				],
-				rentingOrders,
-				completedOrders
+					{ label: '璁㈠崟绫诲瀷', value: '' },
+					{ label: '鑷杞�', value: '0' },
+					{ label: '鐢佃溅', value: '1' }
+				]
 			}
 		},
 		computed: {
 			currentVehicleTypeLabel() {
 				const current = this.vehicleTypeOptions.find(item => item.value === this.selectedVehicleType)
-				return current ? current.label : '杞﹁締绫诲瀷'
+				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
-				})
+			currentStatus() {
+				return this.activeTab === 'renting' ? 1 : 4
 			}
 		},
+		watch: {
+			activeTab() {
+				this.resetAndLoad()
+			},
+			selectedVehicleType() {
+				this.resetAndLoad()
+			},
+			keyword() {
+				clearTimeout(this.searchTimer)
+				this.searchTimer = setTimeout(() => {
+					this.resetAndLoad()
+				}, 300)
+			}
+		},
+		onLoad() {
+			this.getList()
+		},
+		onReachBottom() {
+			this.getList()
+		},
+		onUnload() {
+			clearTimeout(this.searchTimer)
+		},
 		methods: {
+			handleSearch() {
+				clearTimeout(this.searchTimer)
+				this.resetAndLoad()
+			},
 			toggleVehicleType() {
 				this.showVehicleTypePopup = true
 			},
@@ -218,11 +205,247 @@
 				this.selectedVehicleType = value
 				this.showVehicleTypePopup = false
 			},
-			handleAction(text) {
+			resetAndLoad() {
+				this.page = 1
+				this.list = []
+				this.finished = false
+				this.getList()
+			},
+			formatMoneyText(value) {
+				if (value === '' || value === null || value === undefined) {
+					return '-'
+				}
+
+				return `${value}鍏僠
+			},
+			resetRefundState() {
+				this.refundOrderId = ''
+				this.refundInfo = {
+					canBanlanceMoney: '',
+					closeMoney: '',
+					goodsorderMoney: '',
+					hasRefundMoney: ''
+				}
+				this.refundForm = {
+					money: '',
+					reason: ''
+				}
+			},
+			closeRefundPopup() {
+				this.show1 = false
+				this.resetRefundState()
+			},
+			async updateOrderLock(item, lockStatus) {
+				if (!item.bikeCode) {
+					uni.showToast({
+						title: '杞﹁締缂栧彿涓嶈兘涓虹┖',
+						icon: 'none'
+					})
+					return
+				}
+
+				if (this.updatingLock) {
+					return
+				}
+
+				this.updatingLock = true
+
+				try {
+					const res = await this.$u.api.updateLockStatus({
+						ids: item.bikeCode,
+						lockStatus
+					})
+
+					uni.showToast({
+						title: res.code === 200 ? (lockStatus === 1 ? '寮�閿佹垚鍔�' : '鍏抽攣鎴愬姛') : (res.msg || (lockStatus === 1 ? '寮�閿佸け璐�' : '鍏抽攣澶辫触')),
+						icon: 'none'
+					})
+				} catch (error) {
+					uni.showToast({
+						title: error.message || (lockStatus === 1 ? '寮�閿佸け璐�' : '鍏抽攣澶辫触'),
+						icon: 'none'
+					})
+				} finally {
+					this.updatingLock = false
+				}
+			},
+			async openRefundPopup(item) {
+				if (!item.id) {
+					uni.showToast({
+						title: '璁㈠崟ID涓嶈兘涓虹┖',
+						icon: 'none'
+					})
+					return
+				}
+
+				if (this.refundLoading) {
+					return
+				}
+
+				this.refundLoading = true
+
+				try {
+					const res = await this.$u.api.getGoodsorderCanBanlanceDTO({
+						orderId: item.id
+					})
+
+					if (res.code === 200) {
+						this.refundOrderId = item.id
+						this.refundInfo = {
+							canBanlanceMoney: res.data ? res.data.canBanlanceMoney : '',
+							closeMoney: res.data ? res.data.closeMoney : '',
+							goodsorderMoney: res.data ? res.data.goodsorderMoney : '',
+							hasRefundMoney: res.data ? res.data.hasRefundMoney : ''
+						}
+						this.refundForm = {
+							money: '',
+							reason: ''
+						}
+						this.show1 = true
+					}
+
+					
+				} finally {
+					this.refundLoading = false
+				}
+			},
+			async confirmRefund() {
+				if (!this.refundOrderId) {
+					uni.showToast({
+						title: '璁㈠崟ID涓嶈兘涓虹┖',
+						icon: 'none'
+					})
+					return
+				}
+
+				if (!this.refundForm.money) {
+					uni.showToast({
+						title: '璇疯緭鍏ラ��娆鹃噾棰�',
+						icon: 'none'
+					})
+					return
+				}
+
+				if (this.refundLoading) {
+					return
+				}
+
+				this.refundLoading = true
+
+				try {
+					const res = await this.$u.api.backGoodsorder({
+						orderId: this.refundOrderId,
+						reason: this.refundForm.reason.trim(),
+						money: this.refundForm.money
+					})
+
+					
+
+					if (res.code === 200) {
+						this.closeRefundPopup()
+						this.resetAndLoad()
+						uni.showToast({
+							title: '閫�娆炬垚鍔�',
+							icon: 'none'
+						})
+					}
+				} finally {
+					this.refundLoading = false
+				}
+			},
+			async confirmForceBack() {
+				if (!this.currentOrderId) {
+					uni.showToast({
+						title: '璁㈠崟ID涓嶈兘涓虹┖',
+						icon: 'none'
+					})
+					return
+				}
+
+				if (this.forceBackLoading) {
+					return
+				}
+
+				this.forceBackLoading = true
+
+				try {
+					const res = await this.$u.api.forceBack({
+						id: this.currentOrderId
+					})
+					if (res.code === 200) {
+						this.show = false
+						this.currentOrderId = ''
+						this.resetAndLoad()
+					}
+				} finally {
+					this.forceBackLoading = false
+				}
+			},
+			formatBikeType(bikeType) {
+				return Number(bikeType) === 1 ? '鐢佃溅' : '鑷杞�'
+			},
+			async getList() {
+				if (this.loading || this.finished) {
+					return
+				}
+
+				this.loading = true
+
+				const model = {
+					phone: this.keyword.trim(),
+					status: this.currentStatus
+				}
+
+				if (this.selectedVehicleType !== '') {
+					model.bikeType = Number(this.selectedVehicleType)
+				}
+
+				try {
+					const res = await this.$u.api.operationOrderPage({
+						capacity: 10,
+						page: this.page,
+						model
+					})
+
+					if (res.code === 200) {
+						const records = (res.data && res.data.records) || []
+						const total = Number(res.data && res.data.total)
+						const list = records.map(item => ({
+							...item,
+							bikeTypeText: this.formatBikeType(item.bikeType)
+						}))
+						
+						this.list.push(...list)
+						this.page += 1
+						
+						if (!records.length || (Number.isFinite(total) && total > 0 ? this.list.length >= total : records.length < 10)) {
+							this.finished = true
+						}
+					}
+				} finally {
+					this.loading = false
+				}
+			},
+			async handleAction(text, item = {}) {
+				if (text === '寮�閿�') {
+					await this.updateOrderLock(item, 1)
+					return
+				}
+
+				if (text === '鍏抽攣') {
+					await this.updateOrderLock(item, 0)
+					return
+				}
+
 				if (text === '寮哄埗杩樿溅') {
+					this.currentOrderId = item.id || ''
 					this.show = true
 				} else if (text === '閫�娆�') {
-					this.show1 = true
+					await this.openRefundPopup(item)
+				} else if (text === '鏌ョ湅杞ㄨ抗') {
+					uni.navigateTo({
+						url: `/pages/trajectory/trajectory?id=${item.id}`
+					})
 				}
 				// uni.showToast({
 				// 	title: `${text}鍔熻兘寰呮帴鍏,
@@ -416,6 +639,7 @@
 		margin-left: 16rpx;
 		font-size: 26rpx;
 		color: #333333;
+		background: transparent;
 	}
 
 	.search-box__placeholder {
@@ -488,14 +712,6 @@
 		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;
@@ -503,6 +719,14 @@
 		line-height: 44rpx;
 	}
 
+	.load-more-tip {
+		padding: 28rpx 0 10rpx;
+		font-size: 24rpx;
+		line-height: 36rpx;
+		text-align: center;
+		color: #999999;
+	}
+
 	.order-card__footer {
 		margin-top: 22rpx;
 		padding: 18rpx 0 20rpx;

--
Gitblit v1.9.3