feat(订单管理): 添加订单详情弹窗组件及样式
实现订单详情弹窗功能,包含订单信息、商品详情、交易信息和评价展示 重构评价弹窗布局,优化样式和交互体验
Showing
2 changed files
with
431 additions
and
221 deletions
| ... | @@ -382,6 +382,189 @@ | ... | @@ -382,6 +382,189 @@ |
| 382 | } | 382 | } |
| 383 | } | 383 | } |
| 384 | 384 | ||
| 385 | +/* 订单详情弹窗样式 */ | ||
| 386 | +.order-detail-popup { | ||
| 387 | + padding: 40rpx; | ||
| 388 | + height: 100%; | ||
| 389 | + display: flex; | ||
| 390 | + flex-direction: column; | ||
| 391 | + | ||
| 392 | + .detail-header { | ||
| 393 | + text-align: center; | ||
| 394 | + margin-bottom: 40rpx; | ||
| 395 | + | ||
| 396 | + .detail-title { | ||
| 397 | + font-size: 36rpx; | ||
| 398 | + font-weight: 600; | ||
| 399 | + color: #333; | ||
| 400 | + } | ||
| 401 | + } | ||
| 402 | + | ||
| 403 | + .detail-content { | ||
| 404 | + flex: 1; | ||
| 405 | + overflow-y: auto; | ||
| 406 | + | ||
| 407 | + .detail-section { | ||
| 408 | + margin-bottom: 40rpx; | ||
| 409 | + background: #fff; | ||
| 410 | + border-radius: 16rpx; | ||
| 411 | + padding: 30rpx; | ||
| 412 | + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); | ||
| 413 | + | ||
| 414 | + .section-title { | ||
| 415 | + font-size: 32rpx; | ||
| 416 | + font-weight: 600; | ||
| 417 | + color: #333; | ||
| 418 | + margin-bottom: 24rpx; | ||
| 419 | + display: block; | ||
| 420 | + border-bottom: 1rpx solid #f0f0f0; | ||
| 421 | + padding-bottom: 16rpx; | ||
| 422 | + } | ||
| 423 | + | ||
| 424 | + .info-row { | ||
| 425 | + display: flex; | ||
| 426 | + justify-content: space-between; | ||
| 427 | + margin-bottom: 16rpx; | ||
| 428 | + | ||
| 429 | + .info-label { | ||
| 430 | + font-size: 28rpx; | ||
| 431 | + color: #666; | ||
| 432 | + } | ||
| 433 | + | ||
| 434 | + .info-value { | ||
| 435 | + font-size: 28rpx; | ||
| 436 | + color: #333; | ||
| 437 | + font-weight: 500; | ||
| 438 | + | ||
| 439 | + &.status-pending { | ||
| 440 | + color: #f97316; | ||
| 441 | + } | ||
| 442 | + | ||
| 443 | + &.status-completed { | ||
| 444 | + color: #10b981; | ||
| 445 | + } | ||
| 446 | + | ||
| 447 | + &.status-cancelled { | ||
| 448 | + color: #6b7280; | ||
| 449 | + } | ||
| 450 | + | ||
| 451 | + &.price { | ||
| 452 | + color: #f97316; | ||
| 453 | + font-weight: 600; | ||
| 454 | + } | ||
| 455 | + } | ||
| 456 | + } | ||
| 457 | + | ||
| 458 | + .product-detail-info { | ||
| 459 | + display: flex; | ||
| 460 | + background: #f8f9fa; | ||
| 461 | + border-radius: 12rpx; | ||
| 462 | + padding: 20rpx; | ||
| 463 | + | ||
| 464 | + .product-detail-image { | ||
| 465 | + width: 180rpx; | ||
| 466 | + height: 180rpx; | ||
| 467 | + border-radius: 12rpx; | ||
| 468 | + margin-right: 24rpx; | ||
| 469 | + } | ||
| 470 | + | ||
| 471 | + .product-detail-content { | ||
| 472 | + flex: 1; | ||
| 473 | + display: flex; | ||
| 474 | + flex-direction: column; | ||
| 475 | + justify-content: space-between; | ||
| 476 | + | ||
| 477 | + .product-detail-name { | ||
| 478 | + font-size: 32rpx; | ||
| 479 | + font-weight: 600; | ||
| 480 | + color: #333; | ||
| 481 | + margin-bottom: 8rpx; | ||
| 482 | + } | ||
| 483 | + | ||
| 484 | + .product-detail-specs { | ||
| 485 | + font-size: 26rpx; | ||
| 486 | + color: #666; | ||
| 487 | + margin-bottom: 8rpx; | ||
| 488 | + } | ||
| 489 | + | ||
| 490 | + .product-detail-battery { | ||
| 491 | + font-size: 26rpx; | ||
| 492 | + color: #666; | ||
| 493 | + margin-bottom: 16rpx; | ||
| 494 | + } | ||
| 495 | + | ||
| 496 | + .product-detail-price { | ||
| 497 | + font-size: 32rpx; | ||
| 498 | + font-weight: 600; | ||
| 499 | + color: #ff6b35; | ||
| 500 | + } | ||
| 501 | + } | ||
| 502 | + } | ||
| 503 | + | ||
| 504 | + .review-info { | ||
| 505 | + background: #f8f9fa; | ||
| 506 | + border-radius: 12rpx; | ||
| 507 | + padding: 20rpx; | ||
| 508 | + | ||
| 509 | + .review-rating { | ||
| 510 | + display: flex; | ||
| 511 | + align-items: center; | ||
| 512 | + margin-bottom: 16rpx; | ||
| 513 | + | ||
| 514 | + .rating-label { | ||
| 515 | + font-size: 28rpx; | ||
| 516 | + color: #666; | ||
| 517 | + margin-right: 16rpx; | ||
| 518 | + } | ||
| 519 | + | ||
| 520 | + .rating-text { | ||
| 521 | + font-size: 26rpx; | ||
| 522 | + color: #666; | ||
| 523 | + margin-left: 16rpx; | ||
| 524 | + } | ||
| 525 | + } | ||
| 526 | + | ||
| 527 | + .review-content { | ||
| 528 | + margin-bottom: 16rpx; | ||
| 529 | + | ||
| 530 | + .content-label { | ||
| 531 | + font-size: 28rpx; | ||
| 532 | + color: #666; | ||
| 533 | + margin-bottom: 8rpx; | ||
| 534 | + display: block; | ||
| 535 | + } | ||
| 536 | + | ||
| 537 | + .content-text { | ||
| 538 | + font-size: 28rpx; | ||
| 539 | + color: #333; | ||
| 540 | + line-height: 1.5; | ||
| 541 | + } | ||
| 542 | + } | ||
| 543 | + | ||
| 544 | + .review-time { | ||
| 545 | + text-align: right; | ||
| 546 | + | ||
| 547 | + .time-text { | ||
| 548 | + font-size: 24rpx; | ||
| 549 | + color: #999; | ||
| 550 | + } | ||
| 551 | + } | ||
| 552 | + } | ||
| 553 | + } | ||
| 554 | + } | ||
| 555 | + | ||
| 556 | + .detail-footer { | ||
| 557 | + padding-top: 40rpx; | ||
| 558 | + | ||
| 559 | + .nut-button { | ||
| 560 | + height: 88rpx; | ||
| 561 | + border-radius: 44rpx; | ||
| 562 | + font-size: 32rpx; | ||
| 563 | + font-weight: 600; | ||
| 564 | + } | ||
| 565 | + } | ||
| 566 | +} | ||
| 567 | + | ||
| 385 | /* 响应式适配 */ | 568 | /* 响应式适配 */ |
| 386 | @media (max-width: 750px) { | 569 | @media (max-width: 750px) { |
| 387 | .header { | 570 | .header { | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2022-09-19 14:11:06 | 2 | * @Date: 2022-09-19 14:11:06 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-07-03 16:32:53 | 4 | + * @LastEditTime: 2025-07-03 16:56:05 |
| 5 | * @FilePath: /jgdl/src/pages/myOrders/index.vue | 5 | * @FilePath: /jgdl/src/pages/myOrders/index.vue |
| 6 | * @Description: 订单管理页面 | 6 | * @Description: 订单管理页面 |
| 7 | --> | 7 | --> |
| 8 | <template> | 8 | <template> |
| 9 | <view class="order-management-page"> | 9 | <view class="order-management-page"> |
| 10 | <nut-sticky> | 10 | <nut-sticky> |
| 11 | - <!-- 买车/卖车切换 --> | 11 | + <!-- 买车/卖车切换 --> |
| 12 | - <view id="mode-toggle" class="view-mode-toggle"> | 12 | + <view id="mode-toggle" class="view-mode-toggle"> |
| 13 | - <view class="toggle-container"> | 13 | + <view class="toggle-container"> |
| 14 | - <view | 14 | + <view class="toggle-option" :class="{ active: viewMode === 'bought' }" @click="setViewMode('bought')"> |
| 15 | - class="toggle-option" | 15 | + 我买的车 |
| 16 | - :class="{ active: viewMode === 'bought' }" | 16 | + </view> |
| 17 | - @click="setViewMode('bought')" | 17 | + <view class="toggle-option" :class="{ active: viewMode === 'sold' }" @click="setViewMode('sold')"> |
| 18 | - > | 18 | + 我卖的车 |
| 19 | - 我买的车 | 19 | + </view> |
| 20 | - </view> | ||
| 21 | - <view | ||
| 22 | - class="toggle-option" | ||
| 23 | - :class="{ active: viewMode === 'sold' }" | ||
| 24 | - @click="setViewMode('sold')" | ||
| 25 | - > | ||
| 26 | - 我卖的车 | ||
| 27 | </view> | 20 | </view> |
| 28 | </view> | 21 | </view> |
| 29 | - </view> | ||
| 30 | 22 | ||
| 31 | - <!-- 状态筛选标签 --> | 23 | + <!-- 状态筛选标签 --> |
| 32 | - <view id="status-tabs" class="status-tabs"> | 24 | + <view id="status-tabs" class="status-tabs"> |
| 33 | - <view | 25 | + <view class="tab-item" :class="{ active: activeTab === 'all' }" @click="setActiveTab('all')"> |
| 34 | - class="tab-item" | 26 | + 全部 |
| 35 | - :class="{ active: activeTab === 'all' }" | 27 | + </view> |
| 36 | - @click="setActiveTab('all')" | 28 | + <view v-if="viewMode === 'bought'" class="tab-item" :class="{ active: activeTab === 'pending' }" |
| 37 | - > | 29 | + @click="setActiveTab('pending')"> |
| 38 | - 全部 | 30 | + 待支付 |
| 39 | - </view> | 31 | + </view> |
| 40 | - <view | 32 | + <view class="tab-item" :class="{ active: activeTab === 'completed' }" @click="setActiveTab('completed')"> |
| 41 | - v-if="viewMode === 'bought'" | 33 | + 已完成 |
| 42 | - class="tab-item" | 34 | + </view> |
| 43 | - :class="{ active: activeTab === 'pending' }" | 35 | + <view class="tab-item" :class="{ active: activeTab === 'cancelled' }" @click="setActiveTab('cancelled')"> |
| 44 | - @click="setActiveTab('pending')" | 36 | + 已取消 |
| 45 | - > | 37 | + </view> |
| 46 | - 待支付 | ||
| 47 | - </view> | ||
| 48 | - <view | ||
| 49 | - class="tab-item" | ||
| 50 | - :class="{ active: activeTab === 'completed' }" | ||
| 51 | - @click="setActiveTab('completed')" | ||
| 52 | - > | ||
| 53 | - 已完成 | ||
| 54 | - </view> | ||
| 55 | - <view | ||
| 56 | - class="tab-item" | ||
| 57 | - :class="{ active: activeTab === 'cancelled' }" | ||
| 58 | - @click="setActiveTab('cancelled')" | ||
| 59 | - > | ||
| 60 | - 已取消 | ||
| 61 | </view> | 38 | </view> |
| 62 | - </view> | ||
| 63 | </nut-sticky> | 39 | </nut-sticky> |
| 64 | 40 | ||
| 65 | <!-- 订单列表 --> | 41 | <!-- 订单列表 --> |
| 66 | <view class="order-list"> | 42 | <view class="order-list"> |
| 67 | <!-- 滚动列表 --> | 43 | <!-- 滚动列表 --> |
| 68 | - <scroll-view | 44 | + <scroll-view class="order-scroll-view" :style="scrollStyle" :scroll-y="true" @scrolltolower="loadMore" |
| 69 | - class="order-scroll-view" | 45 | + @scroll="scroll" :lower-threshold="50" :enable-flex="false"> |
| 70 | - :style="scrollStyle" | ||
| 71 | - :scroll-y="true" | ||
| 72 | - @scrolltolower="loadMore" | ||
| 73 | - @scroll="scroll" | ||
| 74 | - :lower-threshold="50" | ||
| 75 | - :enable-flex="false" | ||
| 76 | - > | ||
| 77 | <!-- 空状态 --> | 46 | <!-- 空状态 --> |
| 78 | <view v-if="filteredOrders.length === 0" class="empty-state"> | 47 | <view v-if="filteredOrders.length === 0" class="empty-state"> |
| 79 | <text class="empty-text">暂无订单</text> | 48 | <text class="empty-text">暂无订单</text> |
| ... | @@ -81,84 +50,59 @@ | ... | @@ -81,84 +50,59 @@ |
| 81 | 50 | ||
| 82 | <!-- 订单卡片 --> | 51 | <!-- 订单卡片 --> |
| 83 | <view v-else> | 52 | <view v-else> |
| 84 | - <view | 53 | + <view v-for="order in filteredOrders" :key="order.id" class="order-card"> |
| 85 | - v-for="order in filteredOrders" | 54 | + <!-- 订单头部信息 --> |
| 86 | - :key="order.id" | 55 | + <view class="order-header"> |
| 87 | - class="order-card" | 56 | + <text class="order-date">{{ order.date }}</text> |
| 88 | - > | 57 | + <text class="order-status" :class="getStatusClass(order.status)"> |
| 89 | - <!-- 订单头部信息 --> | 58 | + {{ getStatusText(order.status) }} |
| 90 | - <view class="order-header"> | 59 | + </text> |
| 91 | - <text class="order-date">{{ order.date }}</text> | 60 | + </view> |
| 92 | - <text class="order-status" :class="getStatusClass(order.status)"> | ||
| 93 | - {{ getStatusText(order.status) }} | ||
| 94 | - </text> | ||
| 95 | - </view> | ||
| 96 | 61 | ||
| 97 | - <!-- 车辆信息 --> | 62 | + <!-- 车辆信息 --> |
| 98 | - <nut-row :gutter="12" class="vehicle-info"> | 63 | + <nut-row :gutter="12" class="vehicle-info"> |
| 99 | - <nut-col :span="6"> | 64 | + <nut-col :span="6"> |
| 100 | - <image | 65 | + <image :src="order.vehicle.imageUrl" :alt="order.vehicle.name" class="vehicle-image" |
| 101 | - :src="order.vehicle.imageUrl" | 66 | + mode="aspectFill" /> |
| 102 | - :alt="order.vehicle.name" | 67 | + </nut-col> |
| 103 | - class="vehicle-image" | 68 | + <nut-col :span="18"> |
| 104 | - mode="aspectFill" | 69 | + <view class="vehicle-details"> |
| 105 | - /> | 70 | + <text class="vehicle-name">{{ order.vehicle.name }}</text> |
| 106 | - </nut-col> | 71 | + <text class="vehicle-specs"> |
| 107 | - <nut-col :span="18"> | 72 | + {{ order.vehicle.year }} | {{ order.vehicle.mileage }} |
| 108 | - <view class="vehicle-details"> | 73 | + </text> |
| 109 | - <text class="vehicle-name">{{ order.vehicle.name }}</text> | 74 | + <text class="vehicle-battery">{{ order.vehicle.batteryCapacity }}</text> |
| 110 | - <text class="vehicle-specs"> | 75 | + <text class="vehicle-price">¥{{ order.vehicle.price }}</text> |
| 111 | - {{ order.vehicle.year }} | {{ order.vehicle.mileage }} | 76 | + </view> |
| 112 | - </text> | 77 | + </nut-col> |
| 113 | - <text class="vehicle-battery">{{ order.vehicle.batteryCapacity }}</text> | 78 | + </nut-row> |
| 114 | - <text class="vehicle-price">¥{{ order.vehicle.price }}</text> | 79 | + |
| 115 | - </view> | 80 | + <!-- 操作按钮 --> |
| 116 | - </nut-col> | 81 | + <view class="order-actions"> |
| 117 | - </nut-row> | 82 | + <!-- 买车模式:待支付状态 --> |
| 118 | - | 83 | + <template v-if="viewMode === 'bought' && order.status === 'pending'"> |
| 119 | - <!-- 操作按钮 --> | 84 | + <nut-button type="primary" size="small" @click="handlePayment(order)"> |
| 120 | - <view class="order-actions"> | 85 | + 去支付 |
| 121 | - <!-- 买车模式:待支付状态 --> | 86 | + </nut-button> |
| 122 | - <template v-if="viewMode === 'bought' && order.status === 'pending'"> | 87 | + </template> |
| 123 | - <nut-button | 88 | + |
| 124 | - type="primary" | 89 | + <!-- 已完成状态 --> |
| 125 | - size="small" | 90 | + <template v-if="order.status === 'completed'"> |
| 126 | - @click="handlePayment(order)" | 91 | + <nut-button type="default" size="small" @click="viewOrderDetail(order.id)"> |
| 127 | - > | 92 | + 查看详情 |
| 128 | - 去支付 | 93 | + </nut-button> |
| 129 | - </nut-button> | 94 | + <nut-button type="primary" size="small" @click="rateOrder(order.id)" class="ml-2"> |
| 130 | - </template> | 95 | + {{ order.review ? '查看评价' : '评价' }} |
| 131 | - | 96 | + </nut-button> |
| 132 | - <!-- 已完成状态 --> | 97 | + </template> |
| 133 | - <template v-if="order.status === 'completed'"> | 98 | + |
| 134 | - <nut-button | 99 | + <!-- 已取消状态 --> |
| 135 | - type="default" | 100 | + <template v-if="order.status === 'cancelled'"> |
| 136 | - size="small" | 101 | + <nut-button type="default" size="small" @click="deleteOrder(order.id)"> |
| 137 | - @click="viewOrderDetail(order.id)" | 102 | + 删除订单 |
| 138 | - > | 103 | + </nut-button> |
| 139 | - 查看详情 | 104 | + </template> |
| 140 | - </nut-button> | 105 | + </view> |
| 141 | - <nut-button | ||
| 142 | - type="primary" | ||
| 143 | - size="small" | ||
| 144 | - @click="rateOrder(order.id)" | ||
| 145 | - class="ml-2" | ||
| 146 | - > | ||
| 147 | - {{ order.review ? '查看评价' : '评价' }} | ||
| 148 | - </nut-button> | ||
| 149 | - </template> | ||
| 150 | - | ||
| 151 | - <!-- 已取消状态 --> | ||
| 152 | - <template v-if="order.status === 'cancelled'"> | ||
| 153 | - <nut-button | ||
| 154 | - type="default" | ||
| 155 | - size="small" | ||
| 156 | - @click="deleteOrder(order.id)" | ||
| 157 | - > | ||
| 158 | - 删除订单 | ||
| 159 | - </nut-button> | ||
| 160 | - </template> | ||
| 161 | - </view> | ||
| 162 | </view> | 106 | </view> |
| 163 | </view> | 107 | </view> |
| 164 | 108 | ||
| ... | @@ -178,80 +122,147 @@ | ... | @@ -178,80 +122,147 @@ |
| 178 | <payCard :visible="show_pay" :data="payData" @close="onPayClose" /> | 122 | <payCard :visible="show_pay" :data="payData" @close="onPayClose" /> |
| 179 | 123 | ||
| 180 | <!-- 评价弹窗 --> | 124 | <!-- 评价弹窗 --> |
| 181 | - <nut-popup | 125 | + <nut-popup v-model:visible="showRatePopup" position="right" :style="{ width: '100%', height: '100%' }" closeable |
| 182 | - v-model:visible="showRatePopup" | 126 | + close-icon-position="top-right" @close="closeRatePopup"> |
| 183 | - position="bottom" | ||
| 184 | - :style="{ height: '60%' }" | ||
| 185 | - round | ||
| 186 | - closeable | ||
| 187 | - @close="closeRatePopup" | ||
| 188 | - > | ||
| 189 | <view class="rate-popup"> | 127 | <view class="rate-popup"> |
| 190 | <view class="rate-header"> | 128 | <view class="rate-header"> |
| 191 | - <text class="rate-title">评价商品</text> | 129 | + <text class="rate-title">{{ isReadOnlyMode ? '查看评价' : '商品评价' }}</text> |
| 192 | </view> | 130 | </view> |
| 193 | 131 | ||
| 194 | <view class="rate-content"> | 132 | <view class="rate-content"> |
| 195 | - <!-- 商品信息 --> | 133 | + <!-- 商品信息展示 --> |
| 196 | - <view class="product-info" v-if="currentRateOrder"> | 134 | + <view class="product-info"> |
| 197 | - <image | 135 | + <image :src="currentRateOrder?.vehicle?.imageUrl" class="product-image" mode="aspectFill" /> |
| 198 | - :src="currentRateOrder.vehicle.imageUrl" | 136 | + <view class="product-details"> |
| 199 | - class="product-image" | 137 | + <text class="product-name">{{ currentRateOrder?.vehicle?.name }}</text> |
| 200 | - mode="aspectFill" | 138 | + <text class="product-specs">{{ currentRateOrder?.vehicle?.year }} · {{ currentRateOrder?.vehicle?.mileage |
| 201 | - /> | 139 | + }}</text> |
| 202 | - <view class="product-details"> | 140 | + <text class="product-price">¥{{ currentRateOrder?.vehicle?.price }}</text> |
| 203 | - <text class="product-name">{{ currentRateOrder.vehicle.name }}</text> | 141 | + </view> |
| 204 | - <text class="product-specs">{{ currentRateOrder.vehicle.year }} · {{ currentRateOrder.vehicle.mileage }}</text> | 142 | + </view> |
| 205 | - <text class="product-price">¥{{ currentRateOrder.vehicle.price }}</text> | 143 | + |
| 144 | + <!-- 评分组件 --> | ||
| 145 | + <view class="rate-score-section"> | ||
| 146 | + <text class="score-label">{{ isReadOnlyMode ? '评分' : '请给商品评分' }}</text> | ||
| 147 | + <nut-rate v-model="rateScore" :readonly="isReadOnlyMode" :size="isReadOnlyMode ? '20' : '24'" | ||
| 148 | + active-color="#ff6b35" void-color="#e5e5e5" class="rate-stars" /> | ||
| 149 | + <text v-if="isReadOnlyMode" class="score-text">{{ rateScore }}/5分</text> | ||
| 150 | + </view> | ||
| 151 | + | ||
| 152 | + <!-- 评价输入框 --> | ||
| 153 | + <view class="rate-input-section"> | ||
| 154 | + <text class="input-label">{{ isReadOnlyMode ? '评价内容' : '请输入评价内容' }}</text> | ||
| 155 | + <view class="border border-gray-100"> | ||
| 156 | + <nut-textarea v-model="rateContent" :placeholder="isReadOnlyMode ? '' : '请输入您的评价内容...'" :max-length="200" | ||
| 157 | + :rows="4" :show-word-limit="!isReadOnlyMode" :readonly="isReadOnlyMode" | ||
| 158 | + :class="{ 'readonly': isReadOnlyMode }" /> | ||
| 159 | + </view> | ||
| 160 | + <text v-if="isReadOnlyMode && currentRateOrder?.review?.date" class="review-date"> | ||
| 161 | + 评价时间:{{ currentRateOrder?.review?.date }} | ||
| 162 | + </text> | ||
| 163 | + </view> | ||
| 164 | + </view> | ||
| 165 | + | ||
| 166 | + <!-- 提交按钮 --> | ||
| 167 | + <view class="rate-footer" v-if="!isReadOnlyMode"> | ||
| 168 | + <nut-button type="primary" size="large" @click="submitRate" :loading="submittingRate" block> | ||
| 169 | + 提交评价 | ||
| 170 | + </nut-button> | ||
| 171 | + </view> | ||
| 172 | + </view> | ||
| 173 | + </nut-popup> | ||
| 174 | + | ||
| 175 | + <!-- 订单详情弹窗 --> | ||
| 176 | + <nut-popup v-model:visible="showOrderDetailPopup" position="right" :style="{ width: '100%', height: '100%' }" | ||
| 177 | + closeable close-icon-position="top-right" @close="closeOrderDetailPopup"> | ||
| 178 | + <view class="order-detail-popup"> | ||
| 179 | + <view class="detail-header"> | ||
| 180 | + <text class="detail-title">订单详情</text> | ||
| 181 | + </view> | ||
| 182 | + | ||
| 183 | + <view class="detail-content"> | ||
| 184 | + <!-- 订单基本信息 --> | ||
| 185 | + <view class="detail-section"> | ||
| 186 | + <text class="section-title">订单信息</text> | ||
| 187 | + <view class="info-row"> | ||
| 188 | + <text class="info-label">订单编号</text> | ||
| 189 | + <text class="info-value">{{ currentOrderDetail?.id }}</text> | ||
| 190 | + </view> | ||
| 191 | + <view class="info-row"> | ||
| 192 | + <text class="info-label">下单时间</text> | ||
| 193 | + <text class="info-value">{{ currentOrderDetail?.date }}</text> | ||
| 194 | + </view> | ||
| 195 | + <view class="info-row"> | ||
| 196 | + <text class="info-label">订单状态</text> | ||
| 197 | + <text class="info-value" :class="getStatusClass(currentOrderDetail?.status)"> | ||
| 198 | + {{ getStatusText(currentOrderDetail?.status) }} | ||
| 199 | + </text> | ||
| 200 | + </view> | ||
| 201 | + <view class="info-row"> | ||
| 202 | + <text class="info-label">订单金额</text> | ||
| 203 | + <text class="info-value price">¥{{ currentOrderDetail?.price }}</text> | ||
| 204 | + </view> | ||
| 205 | + </view> | ||
| 206 | + | ||
| 207 | + <!-- 商品信息 --> | ||
| 208 | + <view class="detail-section"> | ||
| 209 | + <text class="section-title">商品信息</text> | ||
| 210 | + <view class="product-detail-info"> | ||
| 211 | + <image :src="currentOrderDetail?.vehicle?.imageUrl" class="product-detail-image" mode="aspectFill" /> | ||
| 212 | + <view class="product-detail-content"> | ||
| 213 | + <text class="product-detail-name">{{ currentOrderDetail?.vehicle?.name }}</text> | ||
| 214 | + <text class="product-detail-specs">{{ currentOrderDetail?.vehicle?.year }} · {{ | ||
| 215 | + currentOrderDetail?.vehicle?.mileage }}</text> | ||
| 216 | + <text class="product-detail-battery">{{ currentOrderDetail?.vehicle?.batteryCapacity }}</text> | ||
| 217 | + <text class="product-detail-price">¥{{ currentOrderDetail?.vehicle?.price }}</text> | ||
| 206 | </view> | 218 | </view> |
| 207 | </view> | 219 | </view> |
| 220 | + </view> | ||
| 208 | 221 | ||
| 209 | - <!-- 评分组件 --> | 222 | + <!-- 交易信息 --> |
| 210 | - <view class="rate-score-section"> | 223 | + <view class="detail-section"> |
| 211 | - <text class="score-label">{{ isReadOnlyMode ? '评分' : '请给商品评分' }}</text> | 224 | + <text class="section-title">交易信息</text> |
| 212 | - <nut-rate | 225 | + <view class="info-row"> |
| 213 | - v-model="rateScore" | 226 | + <text class="info-label">{{ viewMode === 'bought' ? '卖家' : '买家' }}</text> |
| 214 | - :readonly="isReadOnlyMode" | 227 | + <text class="info-value">{{ viewMode === 'bought' ? '张先生' : '李女士' }}</text> |
| 215 | - :size="isReadOnlyMode ? '20' : '24'" | 228 | + </view> |
| 216 | - active-color="#ff6b35" | 229 | + <view class="info-row"> |
| 217 | - void-color="#e5e5e5" | 230 | + <text class="info-label">联系电话</text> |
| 218 | - class="rate-stars" | 231 | + <text class="info-value">{{ viewMode === 'bought' ? '138****5678' : '139****1234' }}</text> |
| 219 | - /> | ||
| 220 | - <text v-if="isReadOnlyMode" class="score-text">{{ rateScore }}/5分</text> | ||
| 221 | </view> | 232 | </view> |
| 233 | + <view class="info-row"> | ||
| 234 | + <text class="info-label">交易地点</text> | ||
| 235 | + <text class="info-value">北京市朝阳区望京SOHO</text> | ||
| 236 | + </view> | ||
| 237 | + </view> | ||
| 222 | 238 | ||
| 223 | - <!-- 评价输入框 --> | 239 | + <!-- 评价信息(如果有) --> |
| 224 | - <view class="rate-input-section"> | 240 | + <view class="detail-section" v-if="currentOrderDetail?.review"> |
| 225 | - <text class="input-label">{{ isReadOnlyMode ? '评价内容' : '请输入评价内容' }}</text> | 241 | + <text class="section-title">评价信息</text> |
| 226 | - <view class="border border-gray-100"> | 242 | + <view class="review-info"> |
| 227 | - <nut-textarea | 243 | + <view class="review-rating"> |
| 228 | - v-model="rateContent" | 244 | + <text class="rating-label">评分:</text> |
| 229 | - :placeholder="isReadOnlyMode ? '' : '请输入您的评价内容...'" | 245 | + <nut-rate :model-value="currentOrderDetail?.review?.rating" readonly size="20" active-color="#ff6b35" |
| 230 | - :max-length="200" | 246 | + void-color="#e5e5e5" /> |
| 231 | - :rows="4" | 247 | + <text class="rating-text">{{ currentOrderDetail?.review?.rating }}/5分</text> |
| 232 | - :show-word-limit="!isReadOnlyMode" | 248 | + </view> |
| 233 | - :readonly="isReadOnlyMode" | 249 | + <view class="review-content"> |
| 234 | - :class="{ 'readonly': isReadOnlyMode }" | 250 | + <text class="content-label">评价内容:</text> |
| 235 | - /> | 251 | + <text class="content-text">{{ currentOrderDetail?.review?.content }}</text> |
| 252 | + </view> | ||
| 253 | + <view class="review-time"> | ||
| 254 | + <text class="time-text">评价时间:{{ currentOrderDetail?.review?.date }}</text> | ||
| 236 | </view> | 255 | </view> |
| 237 | - <text v-if="isReadOnlyMode && currentRateOrder?.review?.date" class="review-date"> | ||
| 238 | - 评价时间:{{ currentRateOrder.review.date }} | ||
| 239 | - </text> | ||
| 240 | </view> | 256 | </view> |
| 241 | </view> | 257 | </view> |
| 258 | + </view> | ||
| 242 | 259 | ||
| 243 | - <!-- 提交按钮 --> | 260 | + <!-- 关闭按钮 --> |
| 244 | - <view class="rate-footer" v-if="!isReadOnlyMode"> | 261 | + <view class="detail-footer"> |
| 245 | - <nut-button | 262 | + <nut-button type="primary" size="large" @click="closeOrderDetailPopup" block> |
| 246 | - type="primary" | 263 | + 关闭 |
| 247 | - size="large" | 264 | + </nut-button> |
| 248 | - @click="submitRate" | 265 | + </view> |
| 249 | - :loading="submittingRate" | ||
| 250 | - block | ||
| 251 | - > | ||
| 252 | - 提交评价 | ||
| 253 | - </nut-button> | ||
| 254 | - </view> | ||
| 255 | </view> | 266 | </view> |
| 256 | </nut-popup> | 267 | </nut-popup> |
| 257 | </view> | 268 | </view> |
| ... | @@ -266,7 +277,7 @@ import payCard from '@/components/payCard.vue' | ... | @@ -266,7 +277,7 @@ import payCard from '@/components/payCard.vue' |
| 266 | // NutUI组件已全局注册,无需单独导入Rate | 277 | // NutUI组件已全局注册,无需单独导入Rate |
| 267 | 278 | ||
| 268 | const scrollStyle = ref({ | 279 | const scrollStyle = ref({ |
| 269 | - height: 'calc(100vh)' | 280 | + height: 'calc(100vh)' |
| 270 | }) | 281 | }) |
| 271 | 282 | ||
| 272 | // 页面状态 | 283 | // 页面状态 |
| ... | @@ -277,9 +288,9 @@ const hasMore = ref(true) | ... | @@ -277,9 +288,9 @@ const hasMore = ref(true) |
| 277 | 288 | ||
| 278 | const show_pay = ref(false) | 289 | const show_pay = ref(false) |
| 279 | const payData = ref({ | 290 | const payData = ref({ |
| 280 | - id: '', | 291 | + id: '', |
| 281 | - price: 0, | 292 | + price: 0, |
| 282 | - remain_time: 0 | 293 | + remain_time: 0 |
| 283 | }) | 294 | }) |
| 284 | 295 | ||
| 285 | // 评价相关状态 | 296 | // 评价相关状态 |
| ... | @@ -290,6 +301,10 @@ const rateScore = ref(5) | ... | @@ -290,6 +301,10 @@ const rateScore = ref(5) |
| 290 | const submittingRate = ref(false) | 301 | const submittingRate = ref(false) |
| 291 | const isReadOnlyMode = ref(false) | 302 | const isReadOnlyMode = ref(false) |
| 292 | 303 | ||
| 304 | +// 订单详情相关状态 | ||
| 305 | +const showOrderDetailPopup = ref(false) | ||
| 306 | +const currentOrderDetail = ref(null) | ||
| 307 | + | ||
| 293 | // 模拟订单数据 | 308 | // 模拟订单数据 |
| 294 | const boughtOrders = ref([ | 309 | const boughtOrders = ref([ |
| 295 | { | 310 | { |
| ... | @@ -452,13 +467,13 @@ const loadMore = () => { | ... | @@ -452,13 +467,13 @@ const loadMore = () => { |
| 452 | const getStatusText = (status) => { | 467 | const getStatusText = (status) => { |
| 453 | switch (status) { | 468 | switch (status) { |
| 454 | case 'pending': | 469 | case 'pending': |
| 455 | - return '待支付' | 470 | + return '待完成' |
| 456 | case 'completed': | 471 | case 'completed': |
| 457 | return '已完成' | 472 | return '已完成' |
| 458 | case 'cancelled': | 473 | case 'cancelled': |
| 459 | return '已取消' | 474 | return '已取消' |
| 460 | default: | 475 | default: |
| 461 | - return '' | 476 | + return '未知状态' |
| 462 | } | 477 | } |
| 463 | } | 478 | } |
| 464 | 479 | ||
| ... | @@ -485,9 +500,9 @@ const getStatusClass = (status) => { | ... | @@ -485,9 +500,9 @@ const getStatusClass = (status) => { |
| 485 | */ | 500 | */ |
| 486 | const handlePayment = ({ id, price }) => { | 501 | const handlePayment = ({ id, price }) => { |
| 487 | onPay({ | 502 | onPay({ |
| 488 | - id, | 503 | + id, |
| 489 | - remain_time: 1800, // 30分钟 | 504 | + remain_time: 1800, // 30分钟 |
| 490 | - price | 505 | + price |
| 491 | }) | 506 | }) |
| 492 | } | 507 | } |
| 493 | 508 | ||
| ... | @@ -499,27 +514,39 @@ const handlePayment = ({ id, price }) => { | ... | @@ -499,27 +514,39 @@ const handlePayment = ({ id, price }) => { |
| 499 | * @param {number} payInfo.price - 价格 | 514 | * @param {number} payInfo.price - 价格 |
| 500 | */ | 515 | */ |
| 501 | const onPay = ({ id, remain_time, price }) => { | 516 | const onPay = ({ id, remain_time, price }) => { |
| 502 | - show_pay.value = true | 517 | + show_pay.value = true |
| 503 | - payData.value.id = id | 518 | + payData.value.id = id |
| 504 | - payData.value.price = price | 519 | + payData.value.price = price |
| 505 | - payData.value.remain_time = remain_time | 520 | + payData.value.remain_time = remain_time |
| 506 | } | 521 | } |
| 507 | 522 | ||
| 508 | /** | 523 | /** |
| 509 | * 关闭支付弹框 | 524 | * 关闭支付弹框 |
| 510 | */ | 525 | */ |
| 511 | const onPayClose = () => { | 526 | const onPayClose = () => { |
| 512 | - show_pay.value = false | 527 | + show_pay.value = false |
| 513 | } | 528 | } |
| 514 | 529 | ||
| 515 | /** | 530 | /** |
| 516 | * 查看订单详情 | 531 | * 查看订单详情 |
| 517 | */ | 532 | */ |
| 518 | const viewOrderDetail = (orderId) => { | 533 | const viewOrderDetail = (orderId) => { |
| 519 | - Taro.showToast({ | 534 | + // 找到对应的订单 |
| 520 | - title: '查看订单详情', | 535 | + const orders = viewMode.value === 'bought' ? boughtOrders.value : soldOrders.value |
| 521 | - icon: 'none' | 536 | + const order = orders.find(o => o.id === orderId) |
| 522 | - }) | 537 | + |
| 538 | + if (order) { | ||
| 539 | + currentOrderDetail.value = order | ||
| 540 | + showOrderDetailPopup.value = true | ||
| 541 | + } | ||
| 542 | +} | ||
| 543 | + | ||
| 544 | +/** | ||
| 545 | + * 关闭订单详情弹窗 | ||
| 546 | + */ | ||
| 547 | +const closeOrderDetailPopup = () => { | ||
| 548 | + showOrderDetailPopup.value = false | ||
| 549 | + currentOrderDetail.value = null | ||
| 523 | } | 550 | } |
| 524 | 551 | ||
| 525 | /** | 552 | /** |
| ... | @@ -647,14 +674,14 @@ const deleteOrder = (orderId) => { | ... | @@ -647,14 +674,14 @@ const deleteOrder = (orderId) => { |
| 647 | onMounted(async () => { | 674 | onMounted(async () => { |
| 648 | // TODO: 加载订单数据 | 675 | // TODO: 加载订单数据 |
| 649 | // 设置滚动列表可视高度 | 676 | // 设置滚动列表可视高度 |
| 650 | - const windowHeight = wx.getWindowInfo().windowHeight; | 677 | + const windowHeight = wx.getWindowInfo().windowHeight; |
| 651 | - setTimeout(async () => { | 678 | + setTimeout(async () => { |
| 652 | - const headerHeight = await $('#mode-toggle').height(); | 679 | + const headerHeight = await $('#mode-toggle').height(); |
| 653 | - const navHeight = await $('#status-tabs').height(); | 680 | + const navHeight = await $('#status-tabs').height(); |
| 654 | - scrollStyle.value = { | 681 | + scrollStyle.value = { |
| 655 | - height: windowHeight - headerHeight - navHeight + 'px' | 682 | + height: windowHeight - headerHeight - navHeight + 'px' |
| 656 | - } | 683 | + } |
| 657 | - }, 500); | 684 | + }, 500); |
| 658 | }) | 685 | }) |
| 659 | </script> | 686 | </script> |
| 660 | 687 | ... | ... |
-
Please register or login to post a comment