From 7d242579a0923e7639876797e738a22c45d6e2d0 Mon Sep 17 00:00:00 2001
From: doum <doum>
Date: 星期四, 23 四月 2026 20:07:37 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 app/pages/order/order.vue |  525 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 519 insertions(+), 6 deletions(-)

diff --git a/app/pages/order/order.vue b/app/pages/order/order.vue
index 94d9b9c..d81b4d4 100644
--- a/app/pages/order/order.vue
+++ b/app/pages/order/order.vue
@@ -1,6 +1,70 @@
 <template>
-	<view>
-		
+	<view class="order-page">
+		<view class="order-page__nav" :style="{ paddingTop: statusBarHeight + 'px' }">
+			<view class="order-page__nav-inner">
+				<text class="order-page__nav-title">鎴戠殑璁㈠崟</text>
+			</view>
+		</view>
+
+		<view class="order-page__tabs" :style="{ top: navHeight + 'px' }">
+			<view v-for="tab in displayTabs" :key="tab.value" class="order-page__tab" :class="{ 'order-page__tab--active': activeTab === tab.value }" @click="activeTab = tab.value">
+				<text class="order-page__tab-text">{{ tab.label }}</text>
+				<view v-if="activeTab === tab.value" class="order-page__tab-line"></view>
+			</view>
+		</view>
+
+		<scroll-view class="order-page__body" scroll-y :style="bodyStyle">
+			<view class="order-page__list">
+				<view v-for="item in currentOrders" :key="item.id" class="order-card" @click="goToOrderDetail(item)">
+					<view class="order-card__head">
+					<view class="order-card__head-left">
+						<image class="order-card__badge-icon" :src="getBadgeIcon(item.badge)" mode="widthFix"></image>
+						<text class="order-card__time-text">涓嬪崟鏃堕棿: {{ item.orderTime }}</text>
+					</view>
+						<text class="order-card__status" :class="{ 'order-card__status--highlight': item.actions && item.actions.length }">{{ item.statusText }}</text>
+					</view>
+
+					<view class="order-card__route-item">
+						<view class="order-card__point order-card__point--pickup">鍙�</view>
+						<view class="order-card__route-texts">
+							<text class="order-card__route-title">{{ item.pickupName }}</text>
+							<text class="order-card__route-desc">{{ item.pickupAddress }}</text>
+						</view>
+					</view>
+
+					<view class="order-card__route-item order-card__route-item--delivery">
+						<view class="order-card__point order-card__point--delivery">閫�</view>
+						<view class="order-card__route-texts">
+							<text class="order-card__route-title">{{ item.deliveryName }}</text>
+							<text class="order-card__route-desc">{{ item.deliveryAddress }}</text>
+						</view>
+					</view>
+
+					<view class="order-card__footer">
+						<view class="order-card__arrival">
+							<image class="order-card__clock" src="/static/image/ic_clock@2x.png" mode="aspectFit"></image>
+							<text class="order-card__arrival-text">{{ item.arriveLabel || '閫佽揪鏃堕棿锛�' }}{{ item.arriveTime }}</text>
+						</view>
+						<view class="order-card__price-wrap">
+							<text v-if="item.priceTag" class="order-card__price-tag">{{ item.priceTag }}</text>
+							<text class="order-card__price">{{ item.price }}</text>
+						</view>
+					</view>
+
+					<view v-if="item.actions && item.actions.length" class="order-card__actions">
+						<button
+							v-for="action in item.actions"
+							:key="action.text"
+							class="order-card__action-btn"
+							:class="['order-card__action-btn--' + action.type, { 'order-card__action-btn--primary-fill': action.fill }]"
+							hover-class="order-card__action-btn--hover"
+						>
+							{{ action.text }}
+						</button>
+					</view>
+				</view>
+			</view>
+		</scroll-view>
 	</view>
 </template>
 
@@ -8,12 +72,461 @@
 	export default {
 		data() {
 			return {
-				
-			};
+				statusBarHeight: 0,
+				navHeight: 0,
+				activeTab: 'all',
+				tabs: [
+					{ label: '鍏ㄩ儴', value: 'all' },
+					{ label: '寰呭彇璐�', value: 'pickup' },
+					{ label: '閰嶉�佷腑', value: 'delivering' },
+					{ label: '宸插畬鎴�', value: 'finished' }
+				],
+				orders: [
+					{
+						id: 1,
+						type: 'pickup',
+						badge: '鏍囬�熻揪',
+						badgeType: 'blue',
+						orderTime: '2026-04-12 12:09',
+						statusText: '寰呭彇璐�',
+						pickupName: '涓搧蹇繍鍗楃珯鏃楄埌搴�',
+						pickupAddress: '鑾茶姳璺�200鍙疯幉鑺变骇涓氬洯F鏍�401',
+						deliveryName: '浣宠嫅宸撮粠閮藉競3鏈�10鏍�301瀹�',
+						deliveryAddress: '娲炲涵婀栬矾涓庢箹鍖楄矾浜ゅ弶鍙hタ150绫�',
+						arriveLabel: '',
+						arriveTime: '45鍒嗛挓鍐呴�佽揪',
+						priceTag: '',
+						price: '楼20.5',
+						actions: [
+							{ text: '鍙栨秷璁㈠崟', type: 'light', fill: false },
+							{ text: '鍙栬揣鐮�', type: 'primary', fill: false },
+							{ text: '鎷嶇収鍙栬揣', type: 'primary', fill: true }
+						]
+					},
+					{
+						id: 4,
+						type: 'pickup',
+						badge: '鏋侀�熻揪',
+						badgeType: 'red',
+						orderTime: '2026-04-12 12:33',
+						statusText: '寰呭彇璐�',
+						pickupName: '涓搧蹇繍鍗楃珯鏃楄埌搴�',
+						pickupAddress: '鑾茶姳璺�200鍙疯幉鑺变骇涓氬洯F鏍�401',
+						deliveryName: '浣宠嫅宸撮粠閮藉競3鏈�10鏍�301瀹�',
+						deliveryAddress: '娲炲涵婀栬矾涓庢箹鍖楄矾浜ゅ弶鍙hタ150绫�',
+						arriveLabel: '',
+						arriveTime: '50鍒嗛挓鍐呴�佽揪',
+						priceTag: '',
+						price: '楼20.5',
+						actions: [
+							{ text: '鍙栨秷璁㈠崟', type: 'light', fill: false },
+							{ text: '鍙栬揣鐮�', type: 'primary', fill: false },
+							{ text: '鎷嶇収鍙栬揣', type: 'primary', fill: true }
+						]
+					},
+					{
+						id: 2,
+						type: 'delivering',
+						badge: '鏋侀�熻揪',
+						badgeType: 'red',
+						orderTime: '2026-04-12 12:33',
+						statusText: '閰嶉�佷腑',
+						pickupName: '涓搧蹇繍鍗楃珯鏃楄埌搴�',
+						pickupAddress: '鑾茶姳璺�200鍙疯幉鑺变骇涓氬洯F鏍�401',
+						deliveryName: '浣宠嫅宸撮粠閮藉競3鏈�10鏍�301瀹�',
+						deliveryAddress: '娲炲涵婀栬矾涓庢箹鍖楄矾浜ゅ弶鍙hタ150绫�',
+						arriveLabel: '閫佽揪鏃堕棿锛�',
+						arriveTime: '04-12 12:58',
+						priceTag: '',
+						price: '楼20.5'
+					},
+					{
+						id: 5,
+						type: 'rated',
+						badge: '鏋侀�熻揪',
+						badgeType: 'red',
+						orderTime: '2026-04-12 13:08',
+						statusText: '宸茶瘎浠�',
+						pickupName: '涓搧蹇繍鍗楃珯鏃楄埌搴�',
+						pickupAddress: '鑾茶姳璺�200鍙疯幉鑺变骇涓氬洯F鏍�401',
+						deliveryName: '浣宠嫅宸撮粠閮藉競3鏈�10鏍�301瀹�',
+						deliveryAddress: '娲炲涵婀栬矾涓庢箹鍖楄矾浜ゅ弶鍙hタ150绫�',
+						arriveLabel: '閫佽揪鏃堕棿锛�',
+						arriveTime: '04-12 13:36',
+						priceTag: '',
+						price: '楼18.8'
+					},
+					{
+						id: 6,
+						type: 'cancelled',
+						badge: '鏍囬�熻揪',
+						badgeType: 'blue',
+						orderTime: '2026-04-12 13:18',
+						statusText: '宸插彇娑�',
+						pickupName: '涓搧蹇繍鍗楃珯鏃楄埌搴�',
+						pickupAddress: '鑾茶姳璺�200鍙疯幉鑺变骇涓氬洯F鏍�401',
+						deliveryName: '浣宠嫅宸撮粠閮藉競3鏈�10鏍�301瀹�',
+						deliveryAddress: '娲炲涵婀栬矾涓庢箹鍖楄矾浜ゅ弶鍙hタ150绫�',
+						arriveLabel: '閫佽揪鏃堕棿锛�',
+						arriveTime: '04-12 13:52',
+						priceTag: '',
+						price: '楼16.5'
+					},
+					{
+						id: 3,
+						type: 'finished',
+						badge: '鏋侀�熻揪',
+						badgeType: 'red',
+						orderTime: '2026-04-12 12:33',
+						statusText: '宸插畬鎴�',
+						pickupName: '涓搧蹇繍鍗楃珯鏃楄埌搴�',
+						pickupAddress: '鑾茶姳璺�200鍙疯幉鑺变骇涓氬洯F鏍�401',
+						deliveryName: '浣宠嫅宸撮粠閮藉競3鏈�10鏍�301瀹�',
+						deliveryAddress: '娲炲涵婀栬矾涓庢箹鍖楄矾浜ゅ弶鍙hタ150绫�',
+						arriveLabel: '閫佽揪鏃堕棿锛�',
+						arriveTime: '04-12 12:58',
+						priceTag: '宸茬粨绠�',
+						price: '楼20.5'
+					}
+				]
+			}
+		},
+		computed: {
+			displayTabs() {
+				const countMap = {
+					pickup: this.orders.filter((item) => item.type === 'pickup').length,
+					delivering: this.orders.filter((item) => item.type === 'delivering').length,
+					finished: this.orders.filter((item) => item.type === 'finished').length
+				}
+
+				return this.tabs.map((tab) => {
+					if (!countMap[tab.value]) {
+						return tab
+					}
+
+					return {
+						...tab,
+						label: `${tab.label} ${countMap[tab.value]}`
+					}
+				})
+			},
+
+			bodyStyle() {
+				return {
+					marginTop: this.navHeight + uni.upx2px(88) + 'px',
+					height: `calc(100vh - ${this.navHeight + uni.upx2px(88)}px)`
+				}
+			},
+			currentOrders() {
+				if (this.activeTab === 'all') {
+					return this.orders
+				}
+
+				return this.orders.filter((item) => item.type === this.activeTab)
+			}
+		},
+		onLoad() {
+			const systemInfo = uni.getSystemInfoSync()
+			this.statusBarHeight = systemInfo.statusBarHeight || 0
+			this.navHeight = this.statusBarHeight + uni.upx2px(88)
+		},
+		methods: {
+			getBadgeIcon(badge) {
+				const badgeMap = {
+					'鏋侀�熻揪': '/static/image/ic_jisuda@2x.png',
+					'鏍囬�熻揪': '/static/image/ic_biaosuda@2x.png'
+				}
+
+				return badgeMap[badge] || ''
+			},
+			goToOrderDetail(item) {
+				uni.navigateTo({
+					url: `/pages/order-detail/order-detail?id=${item.id}&status=${item.type === 'delivering' ? 'delivering' : item.type === 'finished' ? 'finished' : item.type === 'cancelled' ? 'cancelled' : item.type === 'rated' ? 'rated' : 'pickup'}`
+				})
+			}
 		}
 	}
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
+	.order-page {
+		height: 100vh;
+		background: #f5f7fb;
+		overflow: hidden;
 
-</style>
\ No newline at end of file
+		&__nav {
+			position: fixed;
+			left: 0;
+			top: 0;
+			right: 0;
+			z-index: 10;
+			background: linear-gradient(180deg, #1f73f6 0%, #1b6cf2 100%);
+		}
+
+		&__nav-inner {
+			height: 88rpx;
+			display: flex;
+			align-items: center;
+			padding: 0 28rpx;
+		}
+
+		&__nav-title {
+			font-size: 38rpx;
+			font-weight: 700;
+			color: #ffffff;
+		}
+
+		&__tabs {
+			position: fixed;
+			left: 0;
+			right: 0;
+			z-index: 9;
+			height: 88rpx;
+			display: flex;
+			align-items: center;
+			background: #ffffff;
+			box-shadow: 0 10rpx 20rpx rgba(40, 72, 128, 0.04);
+		}
+
+		&__tab {
+			position: relative;
+			flex: 1;
+			height: 100%;
+			display: flex;
+			justify-content: center;
+			align-items: center;
+
+			&--active {
+				.order-page__tab-text {
+					color: #272b33;
+					font-weight: 700;
+				}
+			}
+		}
+
+		&__tab-text {
+			font-size: 30rpx;
+			color: #8f96a3;
+		}
+
+		&__tab-line {
+			position: absolute;
+			left: 26rpx;
+			right: 26rpx;
+			bottom: 0;
+			height: 4rpx;
+			border-radius: 999rpx;
+			background: #1a73f8;
+		}
+
+		&__body {
+			box-sizing: border-box;
+		}
+
+		&__list {
+			padding: 18rpx 22rpx calc(env(safe-area-inset-bottom) + 26rpx);
+		}
+	}
+
+	.order-card {
+		margin-bottom: 18rpx;
+		padding: 20rpx 18rpx 18rpx;
+		border-radius: 20rpx;
+		background: #ffffff;
+		box-shadow: 0 8rpx 20rpx rgba(43, 65, 106, 0.05);
+
+		&__head {
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+		}
+
+		&__head-left {
+			display: flex;
+			align-items: center;
+			gap: 12rpx;
+			min-width: 0;
+		}
+
+		&__badge {
+			padding: 4rpx 10rpx;
+			border-radius: 10rpx;
+			font-size: 22rpx;
+			line-height: 1.2;
+			font-weight: 600;
+
+			&--blue {
+				border: 1rpx solid #75cfff;
+				color: #27a8f8;
+				background: #eefaff;
+			}
+
+			&--red {
+				border: 1rpx solid #ff8f8f;
+				color: #ff5d5d;
+				background: #fff1f1;
+			}
+		}
+
+		&__badge-icon {
+			width: 108rpx;
+			height: 40rpx;
+			flex-shrink: 0;
+		}
+
+		&__time-text,
+		&__status,
+		&__route-desc,
+		&__arrival-text {
+			font-size: 24rpx;
+			color: #a1a7b2;
+		}
+
+		&__status {
+			flex-shrink: 0;
+
+			&--highlight {
+				color: #ff4a3d;
+				font-weight: 700;
+			}
+		}
+
+		&__route-item {
+			display: flex;
+			align-items: flex-start;
+			margin-top: 22rpx;
+
+			&--delivery {
+				margin-top: 20rpx;
+			}
+		}
+
+		&__point {
+			width: 34rpx;
+			height: 34rpx;
+			line-height: 34rpx;
+			text-align: center;
+			border-radius: 50%;
+			font-size: 22rpx;
+			font-weight: 700;
+			color: #ffffff;
+			flex-shrink: 0;
+			margin-right: 16rpx;
+
+			&--pickup {
+				background: #2ab8ff;
+			}
+
+			&--delivery {
+				background: #ff9d2e;
+			}
+		}
+
+		&__route-texts {
+			flex: 1;
+			min-width: 0;
+		}
+
+		&__route-title {
+			display: block;
+			font-size: 34rpx;
+			font-weight: 700;
+			color: #2d3139;
+			line-height: 1.3;
+		}
+
+		&__route-desc {
+			display: block;
+			margin-top: 8rpx;
+			line-height: 1.4;
+		}
+
+		&__footer {
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+			margin-top: 22rpx;
+			padding-top: 16rpx;
+			border-top: 1rpx solid #f0f2f6;
+		}
+
+		&__arrival {
+			display: flex;
+			align-items: center;
+			gap: 10rpx;
+		}
+
+		&__clock {
+			width: 24rpx;
+			height: 24rpx;
+			flex-shrink: 0;
+		}
+
+		&__price-wrap {
+			display: flex;
+			align-items: center;
+			gap: 10rpx;
+		}
+
+		&__price-tag {
+			padding: 3rpx 8rpx;
+			border-radius: 8rpx;
+			border: 1rpx solid #ff8f8f;
+			font-size: 22rpx;
+			font-weight: 600;
+			color: #ff6a6a;
+			background: #fff4f4;
+		}
+
+		&__price {
+			font-size: 40rpx;
+			font-weight: 700;
+			color: #ff4030;
+		}
+
+		&__actions {
+			display: flex;
+			justify-content: flex-end;
+			gap: 20rpx;
+			margin-top: 18rpx;
+			padding-top: 18rpx;
+			border-top: 1rpx solid #f0f2f6;
+		}
+
+		&__action-btn {
+			width: 160rpx;
+			height: 64rpx;
+			line-height: 64rpx;
+			padding: 0;
+			border-radius: 34rpx;
+			font-size: 28rpx;
+			font-weight: 500;
+			border: 1rpx solid transparent;
+			background: #ffffff;
+			box-sizing: border-box;
+
+			&::after {
+				border: 0;
+			}
+
+			&--light {
+				border-color: #d7dbe3;
+				color: #8f96a3;
+			}
+
+			&--primary {
+				border-color: #2c7cff;
+				color: #2c7cff;
+			}
+
+			&--primary-fill {
+				background: #2c7cff;
+				color: #ffffff;
+			}
+
+			&--hover {
+				opacity: 0.92;
+			}
+		}
+	}
+</style>

--
Gitblit v1.9.3