feat(订单页面): 改进订单页面交互和样式
- 将删除订单确认弹窗改为统一风格 - 添加订单删除成功提示组件 - 优化切换按钮和标签页的动画效果 - 为订单卡片添加悬停效果和进入动画 - 移除评分显示文本改用纯图标展示
Showing
3 changed files
with
126 additions
and
29 deletions
| 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 13:25:46 | 4 | + * @LastEditTime: 2025-07-03 21:32:33 |
| 5 | * @FilePath: /jgdl/src/pages/myFavorites/index.vue | 5 | * @FilePath: /jgdl/src/pages/myFavorites/index.vue |
| 6 | * @Description: 我的关注页面 | 6 | * @Description: 我的关注页面 |
| 7 | --> | 7 | --> |
| ... | @@ -85,7 +85,7 @@ | ... | @@ -85,7 +85,7 @@ |
| 85 | <!-- Confirmation Modal --> | 85 | <!-- Confirmation Modal --> |
| 86 | <nut-dialog | 86 | <nut-dialog |
| 87 | v-model:visible="showConfirmModal" | 87 | v-model:visible="showConfirmModal" |
| 88 | - title="确认取消关注" | 88 | + title="温馨提示" |
| 89 | content="确定要取消关注此车辆吗?" | 89 | content="确定要取消关注此车辆吗?" |
| 90 | cancel-text="取消" | 90 | cancel-text="取消" |
| 91 | ok-text="确认" | 91 | ok-text="确认" | ... | ... |
| ... | @@ -43,6 +43,8 @@ | ... | @@ -43,6 +43,8 @@ |
| 43 | padding: 8rpx; | 43 | padding: 8rpx; |
| 44 | border-radius: 50rpx; | 44 | border-radius: 50rpx; |
| 45 | display: flex; | 45 | display: flex; |
| 46 | + position: relative; | ||
| 47 | + overflow: hidden; | ||
| 46 | } | 48 | } |
| 47 | 49 | ||
| 48 | .toggle-option { | 50 | .toggle-option { |
| ... | @@ -52,13 +54,21 @@ | ... | @@ -52,13 +54,21 @@ |
| 52 | text-align: center; | 54 | text-align: center; |
| 53 | font-size: 32rpx; /* 增大字体 */ | 55 | font-size: 32rpx; /* 增大字体 */ |
| 54 | color: #6b7280; | 56 | color: #6b7280; |
| 55 | - transition: all 0.2s; | 57 | + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); |
| 56 | cursor: pointer; | 58 | cursor: pointer; |
| 59 | + position: relative; | ||
| 60 | + z-index: 2; | ||
| 61 | + transform: translateX(0); | ||
| 57 | 62 | ||
| 58 | &.active { | 63 | &.active { |
| 59 | background: white; | 64 | background: white; |
| 60 | color: #111827; | 65 | color: #111827; |
| 61 | box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1); | 66 | box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1); |
| 67 | + transform: scale(1.02); | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + &:hover { | ||
| 71 | + transform: translateX(0) scale(1.01); | ||
| 62 | } | 72 | } |
| 63 | } | 73 | } |
| 64 | 74 | ||
| ... | @@ -68,6 +78,14 @@ | ... | @@ -68,6 +78,14 @@ |
| 68 | padding: 20rpx 35rpx; /* 增加内边距 */ | 78 | padding: 20rpx 35rpx; /* 增加内边距 */ |
| 69 | border-bottom: 1rpx solid #e5e7eb; | 79 | border-bottom: 1rpx solid #e5e7eb; |
| 70 | display: flex; | 80 | display: flex; |
| 81 | + position: relative; | ||
| 82 | + overflow-x: auto; | ||
| 83 | + scrollbar-width: none; | ||
| 84 | + -ms-overflow-style: none; | ||
| 85 | + | ||
| 86 | + &::-webkit-scrollbar { | ||
| 87 | + display: none; | ||
| 88 | + } | ||
| 71 | } | 89 | } |
| 72 | 90 | ||
| 73 | .tab-item { | 91 | .tab-item { |
| ... | @@ -77,11 +95,15 @@ | ... | @@ -77,11 +95,15 @@ |
| 77 | color: #6b7280; | 95 | color: #6b7280; |
| 78 | position: relative; | 96 | position: relative; |
| 79 | cursor: pointer; | 97 | cursor: pointer; |
| 80 | - transition: color 0.2s; | 98 | + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); |
| 99 | + white-space: nowrap; | ||
| 100 | + flex-shrink: 0; | ||
| 101 | + transform: translateX(0); | ||
| 81 | 102 | ||
| 82 | &.active { | 103 | &.active { |
| 83 | color: #f97316; | 104 | color: #f97316; |
| 84 | font-weight: 500; | 105 | font-weight: 500; |
| 106 | + transform: translateY(-2rpx); | ||
| 85 | 107 | ||
| 86 | &::after { | 108 | &::after { |
| 87 | content: ''; | 109 | content: ''; |
| ... | @@ -90,16 +112,34 @@ | ... | @@ -90,16 +112,34 @@ |
| 90 | left: 0; | 112 | left: 0; |
| 91 | right: 0; | 113 | right: 0; |
| 92 | height: 4rpx; | 114 | height: 4rpx; |
| 93 | - background: #f97316; | 115 | + background: linear-gradient(90deg, #f97316, #fb923c); |
| 94 | border-radius: 2rpx; | 116 | border-radius: 2rpx; |
| 117 | + animation: slideIn 0.3s cubic-bezier(0.4, 0, 0.2, 1); | ||
| 95 | } | 118 | } |
| 96 | } | 119 | } |
| 97 | 120 | ||
| 121 | + &:hover { | ||
| 122 | + color: #f97316; | ||
| 123 | + transform: translateY(-1rpx); | ||
| 124 | + } | ||
| 125 | + | ||
| 98 | &:last-child { | 126 | &:last-child { |
| 99 | margin-right: 0; | 127 | margin-right: 0; |
| 100 | } | 128 | } |
| 101 | } | 129 | } |
| 102 | 130 | ||
| 131 | +/* 滑入动画 */ | ||
| 132 | +@keyframes slideIn { | ||
| 133 | + 0% { | ||
| 134 | + transform: scaleX(0); | ||
| 135 | + opacity: 0; | ||
| 136 | + } | ||
| 137 | + 100% { | ||
| 138 | + transform: scaleX(1); | ||
| 139 | + opacity: 1; | ||
| 140 | + } | ||
| 141 | +} | ||
| 142 | + | ||
| 103 | /* 订单列表 */ | 143 | /* 订单列表 */ |
| 104 | .order-list { | 144 | .order-list { |
| 105 | flex: 1; | 145 | flex: 1; |
| ... | @@ -139,6 +179,29 @@ | ... | @@ -139,6 +179,29 @@ |
| 139 | padding: 32rpx; | 179 | padding: 32rpx; |
| 140 | border-radius: 16rpx; /* 增加圆角 */ | 180 | border-radius: 16rpx; /* 增加圆角 */ |
| 141 | box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05); /* 添加阴影 */ | 181 | box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05); /* 添加阴影 */ |
| 182 | + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); | ||
| 183 | + transform: translateX(0); | ||
| 184 | + opacity: 1; | ||
| 185 | + | ||
| 186 | + &:hover { | ||
| 187 | + transform: translateY(-4rpx); | ||
| 188 | + box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.1); | ||
| 189 | + } | ||
| 190 | + | ||
| 191 | + /* 卡片进入动画 */ | ||
| 192 | + animation: cardSlideIn 0.4s cubic-bezier(0.4, 0, 0.2, 1); | ||
| 193 | +} | ||
| 194 | + | ||
| 195 | +/* 卡片滑入动画 */ | ||
| 196 | +@keyframes cardSlideIn { | ||
| 197 | + 0% { | ||
| 198 | + transform: translateX(100rpx); | ||
| 199 | + opacity: 0; | ||
| 200 | + } | ||
| 201 | + 100% { | ||
| 202 | + transform: translateX(0); | ||
| 203 | + opacity: 1; | ||
| 204 | + } | ||
| 142 | } | 205 | } |
| 143 | 206 | ||
| 144 | .order-header { | 207 | .order-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 21:14:00 | 4 | + * @LastEditTime: 2025-07-03 21:34:36 |
| 5 | * @FilePath: /jgdl/src/pages/myOrders/index.vue | 5 | * @FilePath: /jgdl/src/pages/myOrders/index.vue |
| 6 | * @Description: 订单管理页面 | 6 | * @Description: 订单管理页面 |
| 7 | --> | 7 | --> |
| ... | @@ -147,7 +147,7 @@ | ... | @@ -147,7 +147,7 @@ |
| 147 | <text class="score-label">{{ isReadOnlyMode ? '评分' : '请给商品评分' }}</text> | 147 | <text class="score-label">{{ isReadOnlyMode ? '评分' : '请给商品评分' }}</text> |
| 148 | <nut-rate v-model="rateScore" :readonly="isReadOnlyMode" :size="isReadOnlyMode ? '20' : '24'" | 148 | <nut-rate v-model="rateScore" :readonly="isReadOnlyMode" :size="isReadOnlyMode ? '20' : '24'" |
| 149 | active-color="#ff6b35" void-color="#e5e5e5" class="rate-stars" /> | 149 | active-color="#ff6b35" void-color="#e5e5e5" class="rate-stars" /> |
| 150 | - <text v-if="isReadOnlyMode" class="score-text">{{ rateScore }}/5分</text> | 150 | + <!-- <text v-if="isReadOnlyMode" class="score-text">{{ rateScore }}/5分</text> --> |
| 151 | </view> | 151 | </view> |
| 152 | 152 | ||
| 153 | <!-- 评价输入框 --> | 153 | <!-- 评价输入框 --> |
| ... | @@ -245,7 +245,7 @@ | ... | @@ -245,7 +245,7 @@ |
| 245 | <text class="rating-label">评分:</text> | 245 | <text class="rating-label">评分:</text> |
| 246 | <nut-rate :model-value="currentOrderDetail?.review?.rating" readonly size="20" active-color="#ff6b35" | 246 | <nut-rate :model-value="currentOrderDetail?.review?.rating" readonly size="20" active-color="#ff6b35" |
| 247 | void-color="#e5e5e5" /> | 247 | void-color="#e5e5e5" /> |
| 248 | - <text class="rating-text">{{ currentOrderDetail?.review?.rating }}/5分</text> | 248 | + <!-- <text class="rating-text">{{ currentOrderDetail?.review?.rating }}/5分</text> --> |
| 249 | </view> | 249 | </view> |
| 250 | <view class="review-content"> | 250 | <view class="review-content"> |
| 251 | <text class="content-label">评价内容:</text> | 251 | <text class="content-label">评价内容:</text> |
| ... | @@ -266,6 +266,24 @@ | ... | @@ -266,6 +266,24 @@ |
| 266 | </view> | 266 | </view> |
| 267 | </view> | 267 | </view> |
| 268 | </nut-popup> | 268 | </nut-popup> |
| 269 | + | ||
| 270 | + <!-- Confirmation Modal --> | ||
| 271 | + <nut-dialog | ||
| 272 | + v-model:visible="showConfirmModal" | ||
| 273 | + title="温馨提示" | ||
| 274 | + content="确定要删除订单吗?" | ||
| 275 | + cancel-text="取消" | ||
| 276 | + ok-text="确认" | ||
| 277 | + @cancel="showConfirmModal = false" | ||
| 278 | + @ok="performDeleteOrder(pendingDeleteOrderId)" | ||
| 279 | + /> | ||
| 280 | + | ||
| 281 | + <!-- 成功提示 --> | ||
| 282 | + <nut-toast | ||
| 283 | + v-model:visible="toastVisible" | ||
| 284 | + :msg="toastMessage" | ||
| 285 | + :type="toastType" | ||
| 286 | + /> | ||
| 269 | </view> | 287 | </view> |
| 270 | </template> | 288 | </template> |
| 271 | 289 | ||
| ... | @@ -880,25 +898,44 @@ const submitRate = async () => { | ... | @@ -880,25 +898,44 @@ const submitRate = async () => { |
| 880 | const deletingOrderId = ref('') | 898 | const deletingOrderId = ref('') |
| 881 | 899 | ||
| 882 | /** | 900 | /** |
| 901 | + * 确认弹窗显示状态 | ||
| 902 | + */ | ||
| 903 | +const showConfirmModal = ref(false) | ||
| 904 | + | ||
| 905 | +/** | ||
| 906 | + * 待删除的订单ID | ||
| 907 | + */ | ||
| 908 | +const pendingDeleteOrderId = ref('') | ||
| 909 | + | ||
| 910 | +/** | ||
| 911 | + * Toast提示 | ||
| 912 | + */ | ||
| 913 | +const toastVisible = ref(false) | ||
| 914 | +const toastMessage = ref('') | ||
| 915 | +const toastType = ref('success') | ||
| 916 | + | ||
| 917 | +/** | ||
| 918 | + * 显示提示信息 | ||
| 919 | + */ | ||
| 920 | +const showToast = (message, type = 'success') => { | ||
| 921 | + toastMessage.value = message | ||
| 922 | + toastType.value = type | ||
| 923 | + toastVisible.value = true | ||
| 924 | +} | ||
| 925 | + | ||
| 926 | +/** | ||
| 883 | * 删除订单 | 927 | * 删除订单 |
| 884 | * @param {string} orderId - 订单ID | 928 | * @param {string} orderId - 订单ID |
| 885 | */ | 929 | */ |
| 886 | const deleteOrder = async (orderId) => { | 930 | const deleteOrder = async (orderId) => { |
| 887 | try { | 931 | try { |
| 888 | - const result = await Taro.showModal({ | 932 | + // 保存待删除的订单ID |
| 889 | - title: '确认删除', | 933 | + pendingDeleteOrderId.value = orderId |
| 890 | - content: '确定要删除这个订单吗?删除后无法恢复。', | 934 | + showConfirmModal.value = true |
| 891 | - confirmText: '删除', | ||
| 892 | - cancelText: '取消' | ||
| 893 | - }) | ||
| 894 | - | ||
| 895 | - if (result.confirm) { | ||
| 896 | - await performDeleteOrder(orderId) | ||
| 897 | - } | ||
| 898 | } catch (error) { | 935 | } catch (error) { |
| 899 | // 用户取消删除或其他错误 | 936 | // 用户取消删除或其他错误 |
| 900 | // console.log('删除操作被取消或出错:', error) | 937 | // console.log('删除操作被取消或出错:', error) |
| 901 | - } | 938 | + } |
| 902 | } | 939 | } |
| 903 | 940 | ||
| 904 | /** | 941 | /** |
| ... | @@ -906,6 +943,9 @@ const deleteOrder = async (orderId) => { | ... | @@ -906,6 +943,9 @@ const deleteOrder = async (orderId) => { |
| 906 | * @param {string} orderId - 订单ID | 943 | * @param {string} orderId - 订单ID |
| 907 | */ | 944 | */ |
| 908 | const performDeleteOrder = async (orderId) => { | 945 | const performDeleteOrder = async (orderId) => { |
| 946 | + // 关闭确认弹窗 | ||
| 947 | + showConfirmModal.value = false | ||
| 948 | + | ||
| 909 | // 设置删除状态,用于显示加载效果 | 949 | // 设置删除状态,用于显示加载效果 |
| 910 | deletingOrderId.value = orderId | 950 | deletingOrderId.value = orderId |
| 911 | 951 | ||
| ... | @@ -934,11 +974,7 @@ const performDeleteOrder = async (orderId) => { | ... | @@ -934,11 +974,7 @@ const performDeleteOrder = async (orderId) => { |
| 934 | if (orderIndex !== -1) { | 974 | if (orderIndex !== -1) { |
| 935 | orders.value.splice(orderIndex, 1) | 975 | orders.value.splice(orderIndex, 1) |
| 936 | 976 | ||
| 937 | - Taro.showToast({ | 977 | + showToast('订单删除成功', 'success') |
| 938 | - title: '订单删除成功', | ||
| 939 | - icon: 'success', | ||
| 940 | - duration: 2000 | ||
| 941 | - }) | ||
| 942 | } else { | 978 | } else { |
| 943 | throw new Error('订单不存在') | 979 | throw new Error('订单不存在') |
| 944 | } | 980 | } |
| ... | @@ -946,14 +982,12 @@ const performDeleteOrder = async (orderId) => { | ... | @@ -946,14 +982,12 @@ const performDeleteOrder = async (orderId) => { |
| 946 | } catch (error) { | 982 | } catch (error) { |
| 947 | // console.error('删除订单失败:', error) | 983 | // console.error('删除订单失败:', error) |
| 948 | 984 | ||
| 949 | - Taro.showToast({ | 985 | + showToast('删除订单失败', 'error') |
| 950 | - title: error.message || '删除失败,请重试', | ||
| 951 | - icon: 'error', | ||
| 952 | - duration: 2000 | ||
| 953 | - }) | ||
| 954 | } finally { | 986 | } finally { |
| 955 | // 清除删除状态 | 987 | // 清除删除状态 |
| 956 | deletingOrderId.value = '' | 988 | deletingOrderId.value = '' |
| 989 | + // 清除待删除订单ID | ||
| 990 | + pendingDeleteOrderId.value = '' | ||
| 957 | } | 991 | } |
| 958 | } | 992 | } |
| 959 | 993 | ... | ... |
-
Please register or login to post a comment