Parcourir la source

AI优化首页、个人中心、订单、站点、设备页面等

skyline il y a 4 mois
Parent
commit
9cd87b4c7b

+ 341 - 242
src/pages-order/detail/index.vue

@@ -1,90 +1,111 @@
 <template>
-  <view class="container">
-    <!-- 订单总览 -->
-    <view class="order-overview">
-      <view class="order-overview_content">
-        <view class="order-overview_amount">
-          <text class="order-overview_currency">¥</text>
-          <text class="order-overview_price">{{ ((state.detail.amount) / 100).toFixed(2) }}</text>
-          <text class="order-overview_unit">元</text>
+  <view class="page-container">
+    <scroll-view class="content-scroll" scroll-y="true">
+      <!-- 金额头部 -->
+      <view class="amount-header">
+        <view class="amount-box">
+          <text class="amount-symbol">¥</text>
+          <text class="amount-number">{{ ((state.detail.amount) / 100).toFixed(2) }}</text>
         </view>
-        <text class="order-overview_type">洗车消费</text>
-      </view>
-    </view>
-
-    <!-- 订单信息 -->
-    <view class="order-info">
-      <view class="order-info_item">
-        <text class="order-info_label">订单编号</text>
-        <text class="order-info_value">
-          {{ state.detail.orderId }}
-          <text class="copy-icon" @click.stop="handleCopy">复制</text>
-        </text>
-      </view>
-      <view class="order-info_item">
-        <text class="order-info_label">总消费金额</text>
-        <text class="order-info_value red">-¥{{ ((state.detail.amount) / 100).toFixed(2) }}元</text>
-      </view>
-      <view class="order-info_item">
-        <text class="order-info_label">充值款支付</text>
-        <text class="order-info_value red">-¥{{ ((state.detail.rechargePayment) / 100).toFixed(2) }}元</text>
-      </view>
-      <view class="order-info_item">
-        <text class="order-info_label">赠款支付</text>
-        <text class="order-info_value red">-¥{{ ((state.detail.grantsPayment) / 100).toFixed(2) }}元</text>
-      </view>
-      <view class="order-info_item">
-        <text class="order-info_label">优惠金额</text>
-        <text class="order-info_value red">-¥{{ ((state.detail.discountMoney) / 100).toFixed(2) }}元</text>
-      </view>
-      <view class="order-info_item">
-        <text class="order-info_label">订单状态</text>
-        <text class="order-info_value" :class="state.detail.orderStatus==0?'primary':(state.detail.orderStatus==1?'success':'error')">
-          {{ fmtDictName('Order.status', state.detail.orderStatus) }}
-        </text>
-      </view>
-      <view class="order-info_item">
-        <text class="order-info_label">支付状态</text>
-        <text class="order-info_value" :class="state.detail.payStatus==0?'primary':(state.detail.payStatus==1?'success':'error')">
+        <text class="amount-type">洗车消费</text>
+        <view class="status-badge" :class="'status-' + (state.detail.payStatus==0?'primary':(state.detail.payStatus==1?'success':'error'))">
           {{ fmtDictName('Order.pay', state.detail.payStatus) }}
-        </text>
-      </view>
-      <view class="order-info_item">
-        <text class="order-info_label">开始时间</text>
-        <text class="order-info_value">{{ fmtDateTime(state.detail.startTime) }}</text>
-      </view>
-      <view class="order-info_item">
-        <text class="order-info_label">结束时间</text>
-        <text class="order-info_value">{{ fmtDateTime(state.detail.endTime) }}</text>
+        </view>
       </view>
-      <view class="order-info_item">
-        <text class="order-info_label">备注</text>
-        <text class="order-info_value">{{ state.detail.remark || '无' }}</text>
+
+      <!-- 订单信息卡片 -->
+      <view class="info-card">
+        <view class="card-header">
+          <view class="header-line"></view>
+          <text class="header-title">订单信息</text>
+        </view>
+        
+        <view class="info-list">
+          <view class="info-item">
+            <text class="info-label">订单编号</text>
+            <view class="info-value-wrap">
+              <text class="info-value">{{ state.detail.orderId }}</text>
+              <text class="copy-btn" @click.stop="handleCopy">
+                <uv-icon name="copy" size="14" color="#fff"></uv-icon>
+              </text>
+            </view>
+          </view>
+          
+          <view class="info-item">
+            <text class="info-label">开始时间</text>
+            <text class="info-value">{{ fmtDateTime(state.detail.startTime) }}</text>
+          </view>
+          
+          <view class="info-item">
+            <text class="info-label">结束时间</text>
+            <text class="info-value">{{ fmtDateTime(state.detail.endTime) }}</text>
+          </view>
+          
+          <view class="info-item">
+            <text class="info-label">订单状态</text>
+            <text class="info-value" :class="'status-' + (state.detail.orderStatus==0?'primary':(state.detail.orderStatus==1?'success':'error'))">
+              {{ fmtDictName('Order.status', state.detail.orderStatus) }}
+            </text>
+          </view>
+          
+          <view class="info-item" v-if="state.detail.remark">
+            <text class="info-label">备注</text>
+            <text class="info-value">{{ state.detail.remark }}</text>
+          </view>
+        </view>
       </view>
-    </view>
 
-    <!-- 金额明细 -->
-    <view class="fee-detail">
-      <view class="fee-detail_header">
-        <text class="fee-detail_title">费用明细</text>
+      <!-- 费用明细卡片 -->
+      <view class="fee-card">
+        <view class="card-header">
+          <view class="header-line"></view>
+          <text class="header-title">费用明细</text>
+        </view>
+        
+        <view class="fee-list">
+          <view class="fee-item" v-for="item in state.detail.orderItems" :key="item.id">
+            <view class="fee-item-left">
+              <text class="fee-name">{{ item.name }}</text>
+              <text class="fee-duration">{{ item.seconds }}</text>
+            </view>
+            <view class="fee-item-right">
+              <text class="fee-price">{{ item.price }}</text>
+              <text class="fee-amount">¥{{ item.amount }}</text>
+            </view>
+          </view>
+        </view>
       </view>
-      <view class="fee-detail_table">
-        <view class="fee-detail_header-row">
-          <text class="fee-detail_header-cell">项目</text>
-          <text class="fee-detail_header-cell">时长</text>
-          <text class="fee-detail_header-cell">单价</text>
-          <text class="fee-detail_header-cell">小计</text>
+
+      <!-- 支付明细卡片 -->
+      <view class="pay-card">
+        <view class="card-header">
+          <view class="header-line"></view>
+          <text class="header-title">支付明细</text>
         </view>
-        <view class="fee-detail_body">
-          <view class="fee-detail_row" v-for="item in state.detail.orderItems" :key="item.id">
-            <text class="fee-detail_cell">{{ item.name }}</text>
-            <text class="fee-detail_cell">{{ item.seconds }}</text>
-            <text class="fee-detail_cell">{{ item.price }}</text>
-            <text class="fee-detail_cell fee-detail_total">¥{{ item.amount }}元</text>
+        
+        <view class="pay-list">
+          <view class="pay-item">
+            <text class="pay-label">总消费金额</text>
+            <text class="pay-value highlight">-¥{{ ((state.detail.amount) / 100).toFixed(2) }}</text>
+          </view>
+          <view class="pay-item">
+            <text class="pay-label">充值款支付</text>
+            <text class="pay-value highlight">-¥{{ ((state.detail.rechargePayment) / 100).toFixed(2) }}</text>
+          </view>
+          <view class="pay-item">
+            <text class="pay-label">赠款支付</text>
+            <text class="pay-value highlight">-¥{{ ((state.detail.grantsPayment) / 100).toFixed(2) }}</text>
+          </view>
+          <view class="pay-item" v-if="state.detail.discountMoney > 0">
+            <text class="pay-label">优惠金额</text>
+            <text class="pay-value success">-¥{{ ((state.detail.discountMoney) / 100).toFixed(2) }}</text>
           </view>
         </view>
       </view>
-    </view>
+      
+      <!-- 底部占位 -->
+      <view style="height: 40rpx;"></view>
+    </scroll-view>
   </view>
 </template>
 
@@ -224,185 +245,263 @@ const fallbackCopy = (orderId: string) => {
 </script>
 
 <style lang="scss" scoped>
-.container {
-  background: #f8f8f8;
-  padding-bottom: 30rpx;
-}
-
-/* 订单总览 */
-.order-overview {
-  margin-top: 20rpx;
-  background: #ffffff;
-  border-radius: 12rpx;
-  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
-  padding: 40rpx 30rpx;
-}
-
-.order-overview_content {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-}
-
-.order-overview_amount {
-  display: flex;
-  align-items: baseline;
-  margin-bottom: 10rpx;
-}
-
-.order-overview_currency {
-  font-size: 32rpx;
-  color: #fa436a;
-  margin-right: 4rpx;
-}
-
-.order-overview_price {
-  font-size: 64rpx;
-  font-weight: 600;
-  color: #fa436a;
-  line-height: 1;
-}
-
-.order-overview_unit {
-  font-size: 32rpx;
-  color: #fa436a;
-  margin-left: 4rpx;
-}
-
-.order-overview_type {
-  font-size: 28rpx;
-  color: #606266;
-}
-
-/* 订单信息 */
-.order-info {
-  margin-top: 20rpx;
-  background: #ffffff;
-  border-radius: 12rpx;
-  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
-  overflow: hidden;
-}
-
-.order-info_item {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  padding: 24rpx 30rpx;
-  border-bottom: 1rpx solid #f0f0f0;
-}
-
-.order-info_item:last-child {
-  border-bottom: none;
-}
-
-.order-info_label {
-  font-size: 28rpx;
-  color: #606266;
-}
-
-.order-info_value {
-  font-size: 28rpx;
-  color: #303133;
-  text-align: right;
-  flex-shrink: 0;
-  margin-left: 40rpx;
-}
-
-.copy-icon {
-  background-color: $uni-color-primary;
-  color: white;
-  padding: 6rpx 16rpx;
-  border-radius: 16rpx;
-  font-size: 22rpx;
-  margin-left: 10rpx;
-  transition: all 0.3s ease;
-  cursor: pointer;
-  display: inline-block;
-}
-
-.copy-icon:active {
-  opacity: 0.8;
-  transform: scale(0.95);
-}
-
-.order-info_value.red {
-  color: #fa436a;
-}
-
-/* 费用明细 */
-.fee-detail {
-  margin-top: 20rpx;
-  background: #ffffff;
-  border-radius: 12rpx;
-  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
-  overflow: hidden;
-}
-
-.fee-detail_header {
-  padding: 24rpx 30rpx;
-  border-bottom: 1rpx solid #f0f0f0;
-}
-
-.fee-detail_title {
-  font-size: 32rpx;
-  font-weight: 500;
-  color: #303133;
+.page-container {
+  width: 100vw;
+  height: 100vh;
+  background: linear-gradient(180deg, #FFE8E8 0%, #FFF5F5 20%, #f5f5f5 40%);
 }
 
-.fee-detail_table {
+.content-scroll {
+  height: 100%;
   width: 100%;
 }
 
-.fee-detail_header-row {
-  display: flex;
-  background-color: #fafafa;
-}
-
-.fee-detail_header-cell {
-  flex: 1;
-  padding: 20rpx;
-  font-size: 26rpx;
-  font-weight: 500;
-  color: #606266;
-  text-align: center;
-}
-
-.fee-detail_body {
-  background-color: #ffffff;
-}
-
-.fee-detail_row {
-  display: flex;
-  border-bottom: 1rpx solid #f0f0f0;
-}
-
-.fee-detail_row:last-child {
-  border-bottom: none;
-}
-
-.fee-detail_cell {
-  flex: 1;
-  padding: 24rpx 20rpx;
-  font-size: 26rpx;
-  color: #303133;
+// 金额头部
+.amount-header {
+  padding: 60rpx 30rpx 40rpx;
   text-align: center;
+  background: linear-gradient(135deg, #C6171E 0%, #E84545 100%);
+  position: relative;
+  
+  .amount-box {
+    display: flex;
+    align-items: baseline;
+    justify-content: center;
+    margin-bottom: 16rpx;
+    
+    .amount-symbol {
+      font-size: 36rpx;
+      color: white;
+      font-weight: 500;
+      margin-right: 8rpx;
+    }
+    
+    .amount-number {
+      font-size: 80rpx;
+      color: white;
+      font-weight: 600;
+      line-height: 1;
+    }
+  }
+  
+  .amount-type {
+    font-size: 28rpx;
+    color: rgba(255, 255, 255, 0.9);
+    margin-bottom: 24rpx;
+    display: block;
+  }
+  
+  .status-badge {
+    display: inline-block;
+    padding: 8rpx 24rpx;
+    border-radius: 20rpx;
+    font-size: 24rpx;
+    font-weight: 500;
+    
+    &.status-primary {
+      background: rgba(255, 255, 255, 0.2);
+      color: white;
+    }
+    
+    &.status-success {
+      background: white;
+      color: #07C160;
+    }
+    
+    &.status-error {
+      background: white;
+      color: #F56C6C;
+    }
+  }
 }
 
-.fee-detail_total {
-  color: #fa436a;
-  font-weight: 500;
+// 卡片通用样式
+.info-card, .fee-card, .pay-card {
+  margin: 24rpx 30rpx;
+  background: white;
+  border-radius: 24rpx;
+  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
+  overflow: hidden;
+  
+  .card-header {
+    display: flex;
+    align-items: center;
+    gap: 12rpx;
+    padding: 28rpx;
+    border-bottom: 1rpx solid #f5f5f5;
+    
+    .header-line {
+      width: 6rpx;
+      height: 28rpx;
+      background: linear-gradient(to bottom, #C6171E, #E84545);
+      border-radius: 3rpx;
+    }
+    
+    .header-title {
+      font-size: 30rpx;
+      font-weight: 600;
+      color: #303133;
+    }
+  }
 }
 
-/* 状态颜色 */
-.primary {
-  color: $uni-color-primary !important;
+// 订单信息
+.info-list {
+  padding: 0 28rpx;
+  
+  .info-item {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 24rpx 0;
+    border-bottom: 1rpx solid #f5f5f5;
+    
+    &:last-child {
+      border-bottom: none;
+    }
+    
+    .info-label {
+      font-size: 26rpx;
+      color: #909399;
+    }
+    
+    .info-value-wrap {
+      display: flex;
+      align-items: center;
+      gap: 12rpx;
+      flex: 1;
+      justify-content: flex-end;
+      
+      .info-value {
+        font-size: 26rpx;
+        color: #303133;
+        text-align: right;
+      }
+      
+      .copy-btn {
+        display: inline-flex;
+        align-items: center;
+        justify-content: center;
+        background: #C6171E;
+        padding: 8rpx 12rpx;
+        border-radius: 12rpx;
+        transition: all 0.2s ease;
+        
+        &:active {
+          opacity: 0.8;
+          transform: scale(0.95);
+        }
+      }
+    }
+    
+    .info-value {
+      font-size: 26rpx;
+      color: #303133;
+      text-align: right;
+      flex: 1;
+      margin-left: 40rpx;
+      
+      &.status-primary {
+        color: #C6171E;
+      }
+      
+      &.status-success {
+        color: #07C160;
+      }
+      
+      &.status-error {
+        color: #F56C6C;
+      }
+    }
+  }
 }
 
-.success {
-  color: $uni-color-success !important;
+// 费用明细
+.fee-list {
+  padding: 0 28rpx;
+  
+  .fee-item {
+    display: flex;
+    justify-content: space-between;
+    align-items: flex-start;
+    padding: 24rpx 0;
+    border-bottom: 1rpx solid #f5f5f5;
+    
+    &:last-child {
+      border-bottom: none;
+    }
+    
+    .fee-item-left {
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      gap: 8rpx;
+      
+      .fee-name {
+        font-size: 28rpx;
+        color: #303133;
+        font-weight: 500;
+      }
+      
+      .fee-duration {
+        font-size: 24rpx;
+        color: #909399;
+      }
+    }
+    
+    .fee-item-right {
+      display: flex;
+      flex-direction: column;
+      align-items: flex-end;
+      gap: 8rpx;
+      
+      .fee-price {
+        font-size: 24rpx;
+        color: #909399;
+      }
+      
+      .fee-amount {
+        font-size: 32rpx;
+        color: #C6171E;
+        font-weight: 600;
+      }
+    }
+  }
 }
 
-.error {
-  color: $uni-color-error !important;
+// 支付明细
+.pay-list {
+  padding: 0 28rpx;
+  
+  .pay-item {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 24rpx 0;
+    border-bottom: 1rpx solid #f5f5f5;
+    
+    &:last-child {
+      border-bottom: none;
+    }
+    
+    .pay-label {
+      font-size: 26rpx;
+      color: #909399;
+    }
+    
+    .pay-value {
+      font-size: 28rpx;
+      color: #303133;
+      font-weight: 500;
+      
+      &.highlight {
+        color: #C6171E;
+      }
+      
+      &.success {
+        color: #07C160;
+      }
+    }
+  }
 }
 </style>

+ 229 - 104
src/pages-order/list/index.vue

@@ -1,41 +1,89 @@
 <template>
-  <view class="container">
-    <uv-list>
-      <uv-list-item
-          clickable show-arrow v-for="(item,index) in state.orderList" :key="index" @click="handleClickDetail(item)">
-        <template #default>
-          <view class="order-card">
-            <view class="order-card_content">
-              <view class="order-card_left">
-                <view class="order-card_info">
-                  <text class="order-card_label">订单编号</text>
-                  <text class="order-card_value">
-                    {{ item.orderId }}
-                    <text class="copy-icon" @click.stop="handleCopy(item.orderId)">复制</text>
-                  </text>
-                </view>
-                <view class="order-card_info">
-                  <text class="order-card_label">消费时间</text>
-                  <text class="order-card_value">{{ fmtDateTime(item.startTime) }}</text>
-                </view>
+  <view class="page-container">
+    <!-- 空状态 -->
+    <view class="empty-wrapper" v-if="!state.orderList || state.orderList.length === 0">
+      <uv-empty 
+        mode="order" 
+        text="暂无订单记录"
+        :marginTop="200"
+      ></uv-empty>
+    </view>
+
+    <!-- 订单列表 -->
+    <scroll-view 
+      v-else
+      class="order-scroll" 
+      scroll-y="true"
+      @scrolltolower="loadMore"
+    >
+      <view class="order-list">
+        <view 
+          class="order-card" 
+          v-for="(item,index) in state.orderList" 
+          :key="index" 
+          @click="handleClickDetail(item)"
+        >
+          <!-- 订单头部 -->
+          <view class="order-header">
+            <view class="order-number">
+              <uv-icon name="order" size="16" color="#C6171E"></uv-icon>
+              <text class="number-text">{{ item.orderId }}</text>
+              <text class="copy-btn" @click.stop="handleCopy(item.orderId)">
+                <uv-icon name="copy" size="14" color="#fff"></uv-icon>
+              </text>
+            </view>
+            <view class="order-status">
+              <uv-text 
+                plain 
+                :size="11"
+                :type="item.payStatus==0?'primary':(item.payStatus==1?'success':'error')"
+                :text="fmtDictName('Order.pay', item.payStatus)"
+              ></uv-text>
+            </view>
+          </view>
+
+          <!-- 订单内容 -->
+          <view class="order-content">
+            <view class="order-info">
+              <view class="info-item">
+                <uv-icon name="clock" size="16" color="#909399"></uv-icon>
+                <text class="info-label">消费时间</text>
+                <text class="info-value">{{ fmtDateTime(item.startTime) }}</text>
               </view>
-              <view class="order-card_right">
-                <text class="order-card_amount">{{ (item.amount / 100).toFixed(2) }}元</text>
-                <uv-text plain :size="12"
-                         :type="item.payStatus==0?'primary':(item.payStatus==1?'success':'error')"
-                         :text="fmtDictName('Order.pay', item.payStatus)"
-                         class="order-card_status">
-                </uv-text>
+            </view>
+
+            <view class="order-amount-box">
+              <view class="amount-label">支付金额</view>
+              <view class="amount-value">
+                <text class="amount-symbol">¥</text>
+                <text class="amount-number">{{ (item.amount / 100).toFixed(2) }}</text>
               </view>
             </view>
           </view>
-        </template>
-      </uv-list-item>
-    </uv-list>
 
-    <uv-load-more :status="computedLoadMoreStatus"
-                  bgColor="#fff"
-                  @loadmore="loadMore" dashed :height="30"/>
+          <!-- 订单底部 -->
+          <view class="order-footer">
+            <view class="footer-tip">
+              <uv-icon name="arrow-right" size="12" color="#C0C4CC"></uv-icon>
+              <text>查看详情</text>
+            </view>
+          </view>
+        </view>
+      </view>
+
+      <!-- 加载更多 -->
+      <view class="load-more-wrapper">
+        <uv-load-more 
+          :status="computedLoadMoreStatus"
+          bgColor="transparent"
+          @loadmore="loadMore" 
+          :height="40"
+        />
+      </view>
+      
+      <!-- 底部占位 -->
+      <view style="height: 40rpx;"></view>
+    </scroll-view>
   </view>
 </template>
 
@@ -163,97 +211,174 @@ const handleCopy = (orderId: string) => {
 </script>
 
 <style lang="scss" scoped>
-.container {
-  background-color: #f6f6f6;
-  padding: 20rpx 0;
-}
-
-.order-card {
-  padding: 24rpx 30rpx;
-  background-color: #ffffff;
-  border-radius: 12rpx;
-  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
-  transition: transform 0.2s, box-shadow 0.2s;
-
-  &:active {
-    transform: translateY(2rpx);
-    box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.05);
-  }
+.page-container {
+  width: 100vw;
+  height: 100vh;
+  background: linear-gradient(180deg, #FFE8E8 0%, #FFF5F5 15%, #f5f5f5 30%);
+  display: flex;
+  flex-direction: column;
 }
 
-.order-card_content {
+// 空状态
+.empty-wrapper {
+  flex: 1;
   display: flex;
-  justify-content: space-between;
   align-items: center;
+  justify-content: center;
 }
 
-.order-card_left {
+// 订单列表滚动区
+.order-scroll {
   flex: 1;
-  display: flex;
-  flex-direction: column;
+  height: 100%;
+  width: 100%;
 }
 
-.order-card_info {
-  display: flex;
-  flex-direction: column;
-  margin-bottom: 12rpx;
+.order-list {
+  padding: 24rpx 30rpx;
 }
 
-.order-card_label {
-  font-size: 24rpx;
-  color: #909399;
-  font-weight: 400;
-}
+// 订单卡片
+.order-card {
+  background: white;
+  border-radius: 24rpx;
+  margin-bottom: 24rpx;
+  overflow: hidden;
+  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
+  transition: all 0.3s ease;
 
-.order-card_value {
-  font-size: 28rpx;
-  color: #303133;
-  font-weight: 500;
-  word-break: break-all;
-  line-height: 1.4;
-  display: flex;
-  align-items: center;
-  gap: 10rpx;
-  flex-wrap: wrap;
-}
+  &:active {
+    transform: scale(0.98);
+    box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
+  }
 
-.copy-icon {
-  background-color: $uni-color-primary;
-  color: white;
-  padding: 4rpx 12rpx;
-  border-radius: 12rpx;
-  font-size: 20rpx;
-  cursor: pointer;
-  display: inline-block;
-  transition: all 0.2s ease;
-  font-weight: normal;
-  margin-left: 8rpx;
+  // 订单头部
+  .order-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 24rpx 28rpx;
+    background: linear-gradient(135deg, rgba(198, 23, 30, 0.03), rgba(232, 69, 69, 0.02));
+    border-bottom: 1rpx solid #f5f5f5;
 
-  &:active {
-    opacity: 0.8;
-    transform: scale(0.95);
+    .order-number {
+      display: flex;
+      align-items: center;
+      gap: 8rpx;
+      flex: 1;
+
+      .number-text {
+        font-size: 26rpx;
+        color: #303133;
+        font-weight: 500;
+      }
+
+      .copy-btn {
+        display: inline-flex;
+        align-items: center;
+        justify-content: center;
+        background: #C6171E;
+        padding: 6rpx 12rpx;
+        border-radius: 12rpx;
+        margin-left: 8rpx;
+        transition: all 0.2s ease;
+
+        &:active {
+          opacity: 0.8;
+          transform: scale(0.95);
+        }
+      }
+    }
+
+    .order-status {
+      flex-shrink: 0;
+    }
   }
-}
 
-.order-card_right {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  min-width: 120rpx;
-}
+  // 订单内容
+  .order-content {
+    padding: 28rpx;
+    display: flex;
+    justify-content: space-between;
+    align-items: flex-start;
 
-.order-card_amount {
-  font-size: 40rpx;
-  font-weight: 700;
-  color: #fa436a;
-  line-height: 1;
-}
+    .order-info {
+      flex: 1;
+
+      .info-item {
+        display: flex;
+        align-items: center;
+        gap: 8rpx;
+        margin-bottom: 16rpx;
+
+        &:last-child {
+          margin-bottom: 0;
+        }
+
+        .info-label {
+          font-size: 24rpx;
+          color: #909399;
+        }
+
+        .info-value {
+          font-size: 26rpx;
+          color: #303133;
+          font-weight: 500;
+        }
+      }
+    }
+
+    .order-amount-box {
+      display: flex;
+      flex-direction: column;
+      align-items: flex-end;
+      gap: 8rpx;
+
+      .amount-label {
+        font-size: 22rpx;
+        color: #909399;
+      }
+
+      .amount-value {
+        display: flex;
+        align-items: baseline;
+        gap: 4rpx;
+
+        .amount-symbol {
+          font-size: 24rpx;
+          color: #C6171E;
+          font-weight: 500;
+        }
 
-.order-card_status {
-  margin-top: 12rpx;
+        .amount-number {
+          font-size: 40rpx;
+          color: #C6171E;
+          font-weight: 600;
+          line-height: 1;
+        }
+      }
+    }
+  }
+
+  // 订单底部
+  .order-footer {
+    padding: 16rpx 28rpx;
+    border-top: 1rpx solid #f5f5f5;
+    display: flex;
+    justify-content: flex-end;
+
+    .footer-tip {
+      display: flex;
+      align-items: center;
+      gap: 4rpx;
+      font-size: 24rpx;
+      color: #909399;
+    }
+  }
 }
 
-.ml10 {
-  margin-left: 10px;
+// 加载更多
+.load-more-wrapper {
+  padding: 20rpx 0;
 }
 </style>

+ 377 - 174
src/pages-wash/device/index.vue

@@ -1,85 +1,93 @@
 <template>
-  <view :class="['page']">
-    <view class="device-card">
-      <view class="device-header">
-        <view class="device-header_name">
-          <text>洗车机编号:No.{{ state.device?.shortId }}</text>
+  <view class="page-container">
+    <scroll-view class="content-scroll" scroll-y="true">
+      <!-- 设备信息卡片 -->
+      <view class="device-info-card">
+        <view class="device-number">
+          <uv-icon name="car" size="24" color="#C6171E"></uv-icon>
+          <text class="number-text">洗车机 No.{{ state.device?.shortId }}</text>
         </view>
-        <view class="device-header_status">
-          <uv-tags plain size="mini" type="error" :text="fmtDictName('WashDevice.state',state.device?.state)"></uv-tags>
+        
+        <view class="device-status" :class="'status-' + (state.device?.state || 'idle')">
+          <view class="status-dot"></view>
+          <text>{{ fmtDictName('WashDevice.state',state.device?.state) }}</text>
         </view>
-        <view class="device-header_fun">
-          <uv-tags 
+        
+        <view class="device-functions">
+          <view 
+            class="function-item" 
             v-for="f in state.device?.functionList" 
-            :key="f" 
-            :text="f" 
-            size="mini" 
-            plain 
-            plainFill 
-            bgColor="#C6171E" 
-            color="white" 
-            type="error"
-            class="device-function-tag"
-          ></uv-tags>
+            :key="f"
+          >
+            <uv-icon name="checkbox-mark" size="14" color="#C6171E"></uv-icon>
+            <text>{{ f }}</text>
+          </view>
         </view>
       </view>
-    </view>
-
-    <view class="device-card device-main">
-      <view class="device-body">
-        <view 
-          class="device-body_ops"
-          :class="{ 'device-body_ops--active': state.device?.state === 'busy' }"
-          @click="debounceStartStopDevice"
-        >
-          <text v-if="state.device?.state==='idle'">启动设备</text>
-          <text v-else>停止设备</text>
+
+      <!-- 操作按钮卡片 -->
+      <view class="control-card">
+        <view class="control-wrapper">
+          <view 
+            class="control-button"
+            :class="{ 'control-button--active': state.device?.state === 'busy' }"
+            @click="debounceStartStopDevice"
+          >
+            <view class="button-icon">
+              <uv-icon 
+                :name="state.device?.state==='idle' ? 'play-circle' : 'stop-circle'" 
+                size="60" 
+                color="#fff"
+              ></uv-icon>
+            </view>
+            <text class="button-text" v-if="state.device?.state==='idle'">启动设备</text>
+            <text class="button-text" v-else>停止设备</text>
+            <text class="button-tip">{{ state.device?.state==='idle' ? '点击开始洗车' : '点击结束洗车' }}</text>
+          </view>
         </view>
       </view>
-    </view>
 
-    <view class="device-card">
-      <view class="device-guide">
-        <view class="device-guide_title">
-          <text>操作指南</text>
+      <!-- 操作指南卡片 -->
+      <view class="guide-card">
+        <view class="card-header">
+          <view class="header-line"></view>
+          <text class="header-title">操作指南</text>
+          <uv-icon name="question-circle" size="18" color="#909399"></uv-icon>
         </view>
-        <view class="device-guide_content">
-          <view class="device-guide_item">
-            <text class="device-guide_item-icon">●</text>
-            <text class="device-guide_item-text">点击上方【启动设备】按钮启动设备;</text>
+        
+        <view class="guide-list">
+          <view class="guide-step" v-for="(step, index) in guideSteps" :key="index">
+            <view class="step-number">{{ index + 1 }}</view>
+            <text class="step-text">{{ step }}</text>
           </view>
-          <view class="device-guide_item">
-            <text class="device-guide_item-icon">●</text>
-            <text class="device-guide_item-text">设备启动后,请在设备功能面板按下功能按键以选择服务项目;</text>
-          </view>
-          <view class="device-guide_item">
-            <text class="device-guide_item-icon">●</text>
-            <text class="device-guide_item-text">洗车过程中再次按下功能按键可以暂停功能,暂停过程中将停止计费,如需恢复请再次按下功能按键;</text>
-          </view>
-          <view class="device-guide_item">
-            <text class="device-guide_item-icon">●</text>
-            <text class="device-guide_item-text">洗车结束后,请按下结算按键或小程序【停止设备】按钮,设备停止运行之后将结束计费;</text>
+        </view>
+      </view>
+
+      <!-- 余额充值卡片 -->
+      <view class="balance-card" v-if="state.isLogin" @click="handleGotoRechage">
+        <view class="balance-left">
+          <view class="balance-icon">
+            <uv-icon name="bag" size="22" color="#C6171E"></uv-icon>
           </view>
-          <view class="device-guide_item">
-            <text class="device-guide_item-icon">●</text>
-            <text class="device-guide_item-text">请在洗车完成后尽快将车辆驶离工位以方便后续用户,谢谢配合。</text>
+          <view class="balance-info">
+            <text class="balance-label">账户余额</text>
+            <view class="balance-amount">
+              <text class="amount-symbol">¥</text>
+              <text class="amount-number">{{ fmtMoney(state.balance) }}</text>
+            </view>
           </view>
         </view>
+        <view class="balance-right">
+          <text class="recharge-text">去充值</text>
+          <uv-icon name="arrow-right" size="16" color="#C6171E"></uv-icon>
+        </view>
       </view>
-    </view>
-
-    <view class="device-card">
-      <view class="device-body_recharge">
-        <uv-button
-            v-if="state.isLogin"
-            shape="circle"
-            type="default"
-            color="#C6171E"
-            @click="handleGotoRechage">余额¥ {{ fmtMoney(state.balance)  }},去充值
-        </uv-button>
-      </view>
-    </view>
+      
+      <!-- 底部占位 -->
+      <view style="height: 40rpx;"></view>
+    </scroll-view>
 
+    <!-- 登录条 -->
     <login-bar class="w100 text-center"></login-bar>
   </view>
 </template>
@@ -93,6 +101,14 @@ import {checkLogin, fetchToken, tryLogin} from "@/utils/auth";
 import {fmtMoney} from "@/utils/common";
 import LoginBar from "@/components/login-bar/index.vue";
 
+const guideSteps = [
+  '点击上方【启动设备】按钮启动设备',
+  '设备启动后,在设备功能面板按下功能按键选择服务项目',
+  '洗车过程中可按功能按键暂停,暂停期间停止计费',
+  '洗车结束后,按结算按键或【停止设备】按钮结束计费',
+  '请及时将车辆驶离工位,方便后续用户使用'
+]
+
 const initState = () => ({
   isLogin:false,
   balance:0,
@@ -305,148 +321,335 @@ const handleGotoRechage = () => {
 </script>
 
 <style lang="scss" scoped>
-.page {
+.page-container {
+  width: 100vw;
   height: 100vh;
-  width: 100%;
-  background-color: #f6f7fa;
-  padding: 20rpx;
-  box-sizing: border-box;
-}
-
-.device-card {
-  background: white;
-  border-radius: 16rpx;
-  padding: 30rpx;
-  margin-bottom: 20rpx;
-  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
+  background: linear-gradient(180deg, #FFE8E8 0%, #FFF5F5 15%, #f5f5f5 30%);
+  display: flex;
+  flex-direction: column;
 }
 
-.device-card.device-main {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  padding: 60rpx 30rpx;
+.content-scroll {
+  flex: 1;
+  height: 100%;
+  width: 100%;
 }
 
-.device-header {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
+// 设备信息卡片
+.device-info-card {
+  margin: 24rpx 30rpx;
+  background: white;
+  border-radius: 24rpx;
+  padding: 32rpx;
+  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
   text-align: center;
-
-  &_name {
-    font-size: 32rpx;
-    font-weight: 600;
-    color: #333;
+  
+  .device-number {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    gap: 8rpx;
     margin-bottom: 20rpx;
+    
+    .number-text {
+      font-size: 32rpx;
+      font-weight: 600;
+      color: #303133;
+    }
   }
-
-  &_status {
-    margin-bottom: 20rpx;
+  
+  .device-status {
+    display: inline-flex;
+    align-items: center;
+    gap: 8rpx;
+    padding: 8rpx 20rpx;
+    border-radius: 20rpx;
+    font-size: 24rpx;
+    font-weight: 500;
+    margin-bottom: 24rpx;
+    
+    .status-dot {
+      width: 12rpx;
+      height: 12rpx;
+      border-radius: 50%;
+      animation: pulse 2s infinite;
+    }
+    
+    &.status-idle {
+      background: #E8F8F0;
+      color: #07C160;
+      
+      .status-dot {
+        background: #07C160;
+      }
+    }
+    
+    &.status-busy {
+      background: #FFF7E6;
+      color: #FAAD14;
+      
+      .status-dot {
+        background: #FAAD14;
+      }
+    }
+    
+    &.status-fault {
+      background: #FEF0F0;
+      color: #F56C6C;
+      
+      .status-dot {
+        background: #F56C6C;
+      }
+    }
   }
-
-  &_fun {
+  
+  .device-functions {
     display: flex;
     flex-wrap: wrap;
     justify-content: center;
-    gap: 10rpx;
-
-    .device-function-tag {
-      margin: 0;
+    gap: 12rpx;
+    
+    .function-item {
+      display: flex;
+      align-items: center;
+      gap: 6rpx;
+      padding: 6rpx 16rpx;
+      background: linear-gradient(135deg, rgba(198, 23, 30, 0.08), rgba(232, 69, 69, 0.05));
+      color: #C6171E;
+      border-radius: 16rpx;
+      font-size: 22rpx;
+      font-weight: 500;
     }
   }
 }
 
-.device-body {
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
-  align-items: center;
-  align-content: center;
-
-  &_recharge {
-    width: 100%;
-    display: flex;
-    justify-content: center;
+@keyframes pulse {
+  0%, 100% {
+    opacity: 1;
+  }
+  50% {
+    opacity: 0.5;
   }
+}
 
-  &_ops {
+// 控制按钮卡片
+.control-card {
+  margin: 0 30rpx 24rpx;
+  background: white;
+  border-radius: 24rpx;
+  padding: 60rpx 32rpx;
+  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
+  
+  .control-wrapper {
     display: flex;
     justify-content: center;
     align-items: center;
-    align-content: center;
-    width: 300rpx;
-    height: 300rpx;
-    border-radius: 50%;
-    background: linear-gradient(135deg, #C6171E 0%, #E63946 100%);
-    color: white;
-    font-size: 36rpx;
-    font-weight: 600;
-    box-shadow: 0 10rpx 30rpx rgba(198, 23, 30, 0.4);
-    transition: all 0.3s ease;
-    position: relative;
-    overflow: hidden;
-
-    &::before {
-      content: '';
-      position: absolute;
-      top: 0;
-      left: 0;
-      right: 0;
-      bottom: 0;
-      background: rgba(255, 255, 255, 0.1);
+    
+    .control-button {
+      width: 320rpx;
+      height: 320rpx;
       border-radius: 50%;
-      transform: scale(0);
-      transition: transform 0.3s ease;
-    }
-
-    &:active {
-      transform: scale(0.95);
-      box-shadow: 0 5rpx 20rpx rgba(198, 23, 30, 0.3);
-
+      background: linear-gradient(135deg, #C6171E 0%, #E84545 100%);
+      display: flex;
+      flex-direction: column;
+      justify-content: center;
+      align-items: center;
+      gap: 12rpx;
+      box-shadow: 0 16rpx 40rpx rgba(198, 23, 30, 0.3);
+      transition: all 0.3s ease;
+      position: relative;
+      overflow: hidden;
+      
       &::before {
-        transform: scale(1);
+        content: '';
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        background: rgba(255, 255, 255, 0.1);
+        border-radius: 50%;
+        transform: scale(0);
+        transition: transform 0.3s ease;
+      }
+      
+      &:active {
+        transform: scale(0.95);
+        box-shadow: 0 8rpx 24rpx rgba(198, 23, 30, 0.3);
+        
+        &::before {
+          transform: scale(1);
+        }
+      }
+      
+      .button-icon {
+        margin-bottom: 8rpx;
+      }
+      
+      .button-text {
+        font-size: 36rpx;
+        font-weight: 600;
+        color: white;
+      }
+      
+      .button-tip {
+        font-size: 22rpx;
+        color: rgba(255, 255, 255, 0.85);
+      }
+      
+      &.control-button--active {
+        background: linear-gradient(135deg, #07C160 0%, #05a050 100%);
+        box-shadow: 0 16rpx 40rpx rgba(7, 193, 96, 0.3);
+        
+        &:active {
+          box-shadow: 0 8rpx 24rpx rgba(7, 193, 96, 0.3);
+        }
       }
     }
+  }
+}
 
-    &--active {
-      background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
-      box-shadow: 0 10rpx 30rpx rgba(76, 175, 80, 0.4);
+// 操作指南卡片
+.guide-card {
+  margin: 0 30rpx 24rpx;
+  background: white;
+  border-radius: 24rpx;
+  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
+  overflow: hidden;
+  
+  .card-header {
+    display: flex;
+    align-items: center;
+    gap: 12rpx;
+    padding: 28rpx;
+    border-bottom: 1rpx solid #f5f5f5;
+    
+    .header-line {
+      width: 6rpx;
+      height: 28rpx;
+      background: linear-gradient(to bottom, #C6171E, #E84545);
+      border-radius: 3rpx;
+    }
+    
+    .header-title {
+      font-size: 30rpx;
+      font-weight: 600;
+      color: #303133;
+      flex: 1;
+    }
+  }
+  
+  .guide-list {
+    padding: 24rpx 28rpx;
+    
+    .guide-step {
+      display: flex;
+      align-items: flex-start;
+      gap: 16rpx;
+      margin-bottom: 20rpx;
+      
+      &:last-child {
+        margin-bottom: 0;
+      }
+      
+      .step-number {
+        width: 40rpx;
+        height: 40rpx;
+        border-radius: 50%;
+        background: linear-gradient(135deg, #C6171E, #E84545);
+        color: white;
+        font-size: 22rpx;
+        font-weight: 600;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        flex-shrink: 0;
+        margin-top: 4rpx;
+      }
+      
+      .step-text {
+        flex: 1;
+        font-size: 26rpx;
+        color: #606266;
+        line-height: 1.6;
+        padding-top: 8rpx;
+      }
     }
   }
 }
 
-.device-guide {
-  &_title {
-    font-size: 30rpx;
-    font-weight: 600;
-    color: #333;
-    margin-bottom: 20rpx;
-    border-bottom: 2rpx solid #f0f0f0;
-    padding-bottom: 15rpx;
+// 余额充值卡片
+.balance-card {
+  margin: 0 30rpx 24rpx;
+  background: white;
+  border-radius: 24rpx;
+  padding: 28rpx 32rpx;
+  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  transition: all 0.3s ease;
+  
+  &:active {
+    transform: scale(0.98);
+    box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
   }
-
-  &_content {
-    font-size: 26rpx;
-    color: #666;
-    line-height: 1.6;
+  
+  .balance-left {
+    display: flex;
+    align-items: center;
+    gap: 16rpx;
+    flex: 1;
+    
+    .balance-icon {
+      width: 56rpx;
+      height: 56rpx;
+      border-radius: 50%;
+      background: linear-gradient(135deg, rgba(198, 23, 30, 0.1), rgba(232, 69, 69, 0.05));
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+    
+    .balance-info {
+      display: flex;
+      flex-direction: column;
+      gap: 6rpx;
+      
+      .balance-label {
+        font-size: 24rpx;
+        color: #909399;
+      }
+      
+      .balance-amount {
+        display: flex;
+        align-items: baseline;
+        gap: 4rpx;
+        
+        .amount-symbol {
+          font-size: 24rpx;
+          color: #C6171E;
+          font-weight: 500;
+        }
+        
+        .amount-number {
+          font-size: 32rpx;
+          color: #C6171E;
+          font-weight: 600;
+        }
+      }
+    }
   }
-
-  &_item {
-    margin-bottom: 15rpx;
+  
+  .balance-right {
     display: flex;
-    align-items: flex-start;
-
-    &-icon {
+    align-items: center;
+    gap: 8rpx;
+    
+    .recharge-text {
+      font-size: 26rpx;
       color: #C6171E;
-      margin-right: 15rpx;
-      font-size: 20rpx;
-      margin-top: 8rpx;
-      flex-shrink: 0;
-    }
-
-    &-text {
-      flex: 1;
+      font-weight: 500;
     }
   }
 }

+ 289 - 193
src/pages-wash/station/index.vue

@@ -1,51 +1,127 @@
 <template>
-  <uv-navbar leftIcon="arrow-left" @leftClick="handleLeftClick" title="门店详情"></uv-navbar>
-  <view class="page">
-    <view class="station-container">
-      <swiper class="station-swiper" indicator-dots indicator-color="rgba(255,255,255,0.5)" indicator-active-color="#fff" autoplay circular>
-        <swiper-item v-for="(img, index) in (state.station.pictures || '').split('|')" :key="index">
-          <image :src="img" mode="aspectFit" class="station-bg"></image>
-        </swiper-item>
-      </swiper>
-    </view>
+  <view class="page-container">
+    <!-- 自定义导航栏 -->
+    <uv-navbar 
+      leftIcon="arrow-left" 
+      @leftClick="handleLeftClick" 
+      title="门店详情"
+      bgColor="#C6171E"
+      :autoBack="true"
+    ></uv-navbar>
+
+    <!-- 内容区域 -->
+    <scroll-view class="content-scroll" scroll-y="true">
+      <!-- 轮播图 -->
+      <view class="swiper-wrapper">
+        <swiper 
+          class="station-swiper" 
+          indicator-dots 
+          indicator-color="rgba(255,255,255,0.5)" 
+          indicator-active-color="#C6171E" 
+          autoplay 
+          circular
+        >
+          <swiper-item v-for="(img, index) in (state.station.pictures || '').split('|')" :key="index">
+            <image :src="img" mode="aspectFill" class="swiper-image"></image>
+          </swiper-item>
+        </swiper>
+      </view>
 
-    <view class="station-info-wrapper">
-      <view class="station-box">
-        <view class="station_wrapper">
-          <WashStation :item="state.station" ref="station_ref"></WashStation>
-        </view>
+      <!-- 站点信息卡片 -->
+      <view class="station-card">
+        <WashStation :item="state.station" ref="station_ref"></WashStation>
       </view>
-    </view>
 
-    <view class="device-box">
-      <view class="device-item" v-for="device in state.deviceList" :key="device.id" @click="handleClickDevice(device)">
-        <view class="device-item_header">
-          <text class="device-item_header-seq">{{ device.seqName }}</text>
-          <text class="device-item_header-status" 
-                :class="getDeviceStatusClass(device.state)">
-            {{ fmtDictName('WashDevice.state', device.state) }}
-          </text>
+      <!-- 设备列表 -->
+      <view class="device-section">
+        <view class="section-header">
+          <view class="header-line"></view>
+          <text class="header-title">可用设备</text>
+          <text class="header-count">{{ state.deviceList.length }}台</text>
         </view>
-        <view class="device-item_body">
-          <view class="device-item_body_header">
-            <text class="device-item_body_header-short">编号:{{ device.shortId }}</text>
-          </view>
-          <view class="device-item_body_func">
-            <view class="device-item_body_func-tag" v-for="(f, index) in device.functionList" :key="index">
-              {{ f }}
+
+        <!-- 空状态 -->
+        <view class="empty-wrapper" v-if="!state.deviceList || state.deviceList.length === 0">
+          <uv-empty 
+            mode="data" 
+            text="暂无可用设备"
+            :marginTop="60"
+          ></uv-empty>
+        </view>
+
+        <!-- 设备列表 -->
+        <view class="device-list" v-else>
+          <view 
+            class="device-card" 
+            v-for="device in state.deviceList" 
+            :key="device.id" 
+            @click="handleClickDevice(device)"
+          >
+            <!-- 设备头部 -->
+            <view class="device-header">
+              <view class="device-name">
+                <uv-icon name="car" size="18" color="#C6171E"></uv-icon>
+                <text>{{ device.seqName }}</text>
+              </view>
+              <view class="device-status" :class="'status-' + getDeviceStatusClass(device.state)">
+                {{ fmtDictName('WashDevice.state', device.state) }}
+              </view>
+            </view>
+
+            <!-- 设备信息 -->
+            <view class="device-info">
+              <view class="info-row">
+                <text class="info-label">设备编号</text>
+                <text class="info-value">{{ device.shortId }}</text>
+              </view>
+            </view>
+
+            <!-- 功能标签 -->
+            <view class="device-functions">
+              <view 
+                class="function-tag" 
+                v-for="(f, index) in device.functionList" 
+                :key="index"
+              >
+                {{ f }}
+              </view>
+            </view>
+
+            <!-- 操作提示 -->
+            <view class="device-action">
+              <uv-icon name="arrow-right" size="14" color="#C0C4CC"></uv-icon>
+              <text>点击选择此设备</text>
             </view>
           </view>
         </view>
       </view>
-    </view>
 
-    <view class="station-bottom">
-      <view class="station-bottom-box">
-        <view class="bottom-left">
-          <uv-button shape="circle" type="info" text="门店导航" @click="handleNavStation"></uv-button>
+      <!-- 底部占位 -->
+      <view style="height: 160rpx;"></view>
+    </scroll-view>
+
+    <!-- 底部操作栏 -->
+    <view class="bottom-bar">
+      <view class="bottom-buttons">
+        <view class="btn-nav">
+          <uv-button 
+            shape="circle" 
+            type="info" 
+            text="门店导航" 
+            @click="handleNavStation"
+            icon="map"
+          ></uv-button>
         </view>
-        <view class="bottom-right">
-          <uv-button shape="circle" type="primary" icon="scan" iconColor="white" color="#C6171E" text="扫码洗车" @click="handleClickScan"></uv-button>
+        <view class="btn-scan">
+          <uv-button 
+            shape="circle" 
+            type="primary" 
+            icon="scan" 
+            iconColor="white" 
+            color="#C6171E" 
+            text="扫码洗车" 
+            @click="handleClickScan"
+          ></uv-button>
         </view>
       </view>
     </view>
@@ -159,197 +235,217 @@ const getDeviceStatusClass = (state: string) => {
 </script>
 
 <style lang="scss" scoped>
-// 品牌主色调
-$brand-primary: #C6171E;
-$brand-primary-light: #F8E4E5;
-$brand-success: #07C160;
-$brand-warning: #FAAD14;
-$brand-error: #F56C6C;
-$text-primary: #333333;
-$text-secondary: #666666;
-$text-tertiary: #999999;
-$border-color: #E4E7ED;
-$background-light: #F5F7FA;
-
-.page {
+.page-container {
+  width: 100vw;
   height: 100vh;
-  width: 100%;
-  background-color: $background-light;
+  background: #f5f5f5;
   display: flex;
   flex-direction: column;
-  padding: 88rpx 0 120rpx;
-  box-sizing: border-box;
-  overflow-x: hidden;
-}
-
-.station-container {
-  width: 100%;
-  padding: 0 20rpx;
-  margin: 20rpx auto 0;
-  position: relative;
-  z-index: 1;
-  box-sizing: border-box;
 }
 
-.station-swiper {
-  height: 400rpx;
-  border-radius: 20rpx;
-  overflow: hidden;
-  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.12);
-}
-
-.station-bg {
-  width: 100%;
+// 内容滚动区
+.content-scroll {
+  flex: 1;
   height: 100%;
-  display: block;
-  margin: auto;
-  border-radius: 20rpx;
-}
-
-.station-info-wrapper {
   width: 100%;
-  padding: 0 20rpx;
-  margin: 20rpx 0;
-  z-index: 10;
-  position: relative;
-  box-sizing: border-box;
 }
 
-.station-box {
-  width: 100%;
-  border-radius: 16rpx;
-  background-color: #fff;
-  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.1);
-  padding: 24rpx;
-  position: relative;
-  z-index: 10;
-  box-sizing: border-box;
+// 轮播图区域
+.swiper-wrapper {
+  padding: 24rpx 30rpx;
+  
+  .station-swiper {
+    height: 360rpx;
+    border-radius: 24rpx;
+    overflow: hidden;
+    box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.1);
+  }
+  
+  .swiper-image {
+    width: 100%;
+    height: 100%;
+  }
 }
 
-.device-box {
-  flex: 1;
-  overflow-y: scroll;
-  width: 100%;
-  padding: 0 30rpx;
-  margin: 30rpx 0 0 0;
-  padding-bottom: 150rpx;
-  max-height: calc(100vh - 600rpx);
-  box-sizing: border-box;
+// 站点信息卡片
+.station-card {
+  margin: 0 30rpx 24rpx;
+  background: white;
+  border-radius: 24rpx;
+  padding: 24rpx;
+  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
 }
 
-.device-item {
-  background-color: #fff;
-  border-radius: 16rpx;
-  margin: 0 auto 24rpx;
-  padding: 20rpx 24rpx;
-  display: flex;
-  flex-direction: column;
-  box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
-  transition: all 0.2s ease;
-  border: 1rpx solid $border-color;
-
-  &:active {
-    transform: scale(0.99);
-    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
-  }
-
-  &_header {
+// 设备区域
+.device-section {
+  margin: 0 30rpx;
+  
+  .section-header {
     display: flex;
-    justify-content: space-between;
     align-items: center;
-    margin-bottom: 16rpx;
-
-    &-seq {
+    gap: 12rpx;
+    margin-bottom: 24rpx;
+    padding: 0 8rpx;
+    
+    .header-line {
+      width: 6rpx;
+      height: 28rpx;
+      background: linear-gradient(to bottom, #C6171E, #E84545);
+      border-radius: 3rpx;
+    }
+    
+    .header-title {
       font-size: 30rpx;
       font-weight: 600;
-      color: $text-primary;
+      color: #303133;
+      flex: 1;
     }
-
-    &-status {
-      font-size: 22rpx;
-      border-radius: 20rpx;
-      padding: 6rpx 20rpx;
-      font-weight: 500;
-      background-color: $brand-primary;
-      color: #fff;
+    
+    .header-count {
+      font-size: 24rpx;
+      color: #909399;
+      background: #f5f5f5;
+      padding: 6rpx 16rpx;
+      border-radius: 12rpx;
     }
   }
+}
 
-  &_body {
-    border-top: 1rpx solid $border-color;
-    padding-top: 16rpx;
-    display: flex;
-    flex-direction: column;
-
-    &_header {
-      margin-bottom: 12rpx;
+// 空状态
+.empty-wrapper {
+  padding: 40rpx 0;
+}
 
-      &-short {
-        font-size: 26rpx;
+// 设备列表
+.device-list {
+  .device-card {
+    background: white;
+    border-radius: 24rpx;
+    padding: 28rpx;
+    margin-bottom: 20rpx;
+    box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
+    transition: all 0.3s ease;
+    
+    &:active {
+      transform: scale(0.98);
+      box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
+    }
+    
+    // 设备头部
+    .device-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 20rpx;
+      
+      .device-name {
+        display: flex;
+        align-items: center;
+        gap: 8rpx;
+        font-size: 28rpx;
+        font-weight: 600;
+        color: #303133;
+      }
+      
+      .device-status {
+        font-size: 22rpx;
+        padding: 6rpx 16rpx;
+        border-radius: 20rpx;
         font-weight: 500;
-        color: $text-secondary;
+        
+        &.status-success {
+          background: #E8F8F0;
+          color: #07C160;
+        }
+        
+        &.status-warning {
+          background: #FFF7E6;
+          color: #FAAD14;
+        }
+        
+        &.status-error {
+          background: #FEF0F0;
+          color: #F56C6C;
+        }
       }
     }
-
-    &_func {
-          display: flex;
-          flex-wrap: wrap;
-          margin-right: -8rpx;
-
-          &-tag {
-            font-size: 18rpx;
-            padding: 2rpx 14rpx;
-            margin-right: 8rpx;
-            margin-bottom: 8rpx;
-            background-color: $brand-primary-light;
-            color: $brand-primary;
-            border-radius: 16rpx;
-            font-weight: 500;
-            line-height: 1.4;
-          }
+    
+    // 设备信息
+    .device-info {
+      padding: 16rpx 0;
+      border-top: 1rpx solid #f5f5f5;
+      border-bottom: 1rpx solid #f5f5f5;
+      
+      .info-row {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        
+        .info-label {
+          font-size: 24rpx;
+          color: #909399;
         }
+        
+        .info-value {
+          font-size: 26rpx;
+          color: #303133;
+          font-weight: 500;
+        }
+      }
+    }
+    
+    // 功能标签
+    .device-functions {
+      display: flex;
+      flex-wrap: wrap;
+      gap: 12rpx;
+      margin: 16rpx 0;
+      
+      .function-tag {
+        font-size: 22rpx;
+        padding: 6rpx 16rpx;
+        background: linear-gradient(135deg, rgba(198, 23, 30, 0.08), rgba(232, 69, 69, 0.05));
+        color: #C6171E;
+        border-radius: 16rpx;
+        font-weight: 500;
+      }
+    }
+    
+    // 操作提示
+    .device-action {
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+      gap: 4rpx;
+      font-size: 24rpx;
+      color: #909399;
+      margin-top: 12rpx;
+    }
   }
 }
 
-.device-item_header-status.success {
-  background-color: $brand-success;
-  color: #fff;
-}
-
-.device-item_header-status.warning {
-  background-color: $brand-warning;
-  color: #fff;
-}
-
-.device-item_header-status.error {
-  background-color: $brand-error;
-  color: #fff;
-}
-
-.station-bottom {
-  width: 100%;
+// 底部操作栏
+.bottom-bar {
   position: fixed;
   bottom: 0;
   left: 0;
-  background-color: #fff;
+  right: 0;
+  background: white;
+  padding: 20rpx 30rpx;
   box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.06);
-  padding: 20rpx;
-  box-sizing: border-box;
   z-index: 100;
-
-  &-box {
-    width: 100%;
+  
+  .bottom-buttons {
     display: flex;
-    justify-content: space-between;
-  }
-
-  .bottom-left {
-    flex: 1;
-    margin-right: 20rpx;
-  }
-
-  .bottom-right {
-    flex: 2;
+    gap: 20rpx;
+    
+    .btn-nav {
+      flex: 1;
+    }
+    
+    .btn-scan {
+      flex: 2;
+    }
   }
 }
 </style>

+ 358 - 294
src/pages/index/index.vue

@@ -1,92 +1,139 @@
 <template>
-  <!--  <uv-navbar placeholder leftIcon="" title="Yeswash洗车"
-               :border="false"></uv-navbar>-->
-  <view class="content">
-    <!--    <image class="logo" src="/static/logo.png"/>
-        <view class="text-area">
-          <text class="title">{{ title }}</text>
-        </view>-->
-    <view style="width: 100%;" class="swiper-content">
-      <swiper :style="state.customStyle" circular :indicator-dots="true" :autoplay="true" :interval="3000"
-              :duration="500">
-        <swiper-item v-for="(item,idx) in state.swiperList" :key="idx">
-          <image :src="item" mode="scaleToFill" :style="state.customStyle" @click="handleBannerClick(idx)"></image>
-        </swiper-item>
-      </swiper>
+  <view class="page-container">
+    <!-- 自定义导航栏 -->
+    <view class="custom-navbar" :style="{paddingTop: statusBarHeight + 'px'}">
+      <view class="navbar-content">
+        <view class="navbar-title">
+          <uv-icon name="home-fill" color="white" size="20"></uv-icon>
+          <text class="title-text">Yeswash洗车</text>
+        </view>
+      </view>
     </view>
 
-    <view class="w100 gap"></view>
-
-    <official-account @binderror="handleOAerror"  @bindload="handleOAload" style="width: 100%"></official-account>
-
-
-    <view class="menu-content w100">
-      <uv-grid :border="false" :col="4">
-        <uv-grid-item v-for="(item,index) in state.menuList" :key="index" @click="handleMenuClick(item)">
-          <image :src="item.icon" mode="widthFit" style="width: 48rpx;height: 48rpx"></image>
-          <text class="grid-text" style="font-size: 14px;">{{ item.title }}</text>
-        </uv-grid-item>
-      </uv-grid>
+    <!-- 优化后的轮播图区域 -->
+    <view class="banner-wrapper">
+      <view class="banner-container">
+        <swiper 
+          class="banner-swiper" 
+          :style="bannerStyle"
+          circular 
+          :indicator-dots="true" 
+          :autoplay="true" 
+          :interval="3000"
+          :duration="500"
+          indicator-color="rgba(255, 255, 255, 0.5)"
+          indicator-active-color="#C6171E"
+        >
+          <swiper-item v-for="(item,idx) in state.swiperList" :key="idx">
+            <image 
+              class="banner-image" 
+              :src="item" 
+              mode="aspectFill" 
+              @click="handleBannerClick(idx)"
+            ></image>
+          </swiper-item>
+        </swiper>
+        
+        <!-- 渐变遮罩层 -->
+        <view class="banner-overlay"></view>
+      </view>
     </view>
 
-    <view class="w100 gap"></view>
-
-    <!--    站点清单  start-->
-    <view class="w100 content_station">
-<!--      <template v-if="isLogin">-->
-        <WashStation v-for="item in state.stationList" :key="item.id" :item="item"></WashStation>
-<!--      </template>-->
-<!--      <uv-empty v-if="!isLogin" mode="order" text="请先登录" :marginTop="100" @click="gotoLogin"></uv-empty>-->
+    <!-- 微信公众号 -->
+    <official-account 
+      @binderror="handleOAerror" 
+      @bindload="handleOAload" 
+      class="official-account"
+    ></official-account>
+
+    <!-- 优化后的菜单区域 -->
+    <view class="menu-section">
+      <view class="menu-card">
+        <view class="menu-header">
+          <view class="menu-title">
+            <view class="title-icon"></view>
+            <text>快捷服务</text>
+          </view>
+        </view>
+        
+        <view class="menu-grid">
+          <view 
+            class="menu-item" 
+            v-for="(item,index) in state.menuList" 
+            :key="index" 
+            @click="handleMenuClick(item)"
+          >
+            <view class="menu-icon-wrapper">
+              <image class="menu-icon" :src="item.icon" mode="aspectFit"></image>
+            </view>
+            <text class="menu-title-text">{{ item.title }}</text>
+          </view>
+        </view>
+      </view>
     </view>
-<!--
-    <movable-area class="mov-area">
-      <movable-view :x="state.screenWidth" :y="state.screenHeight-100" direction="all" @change="onChange" class="customer-service">
-        <button open-type="contact" @contact="handleContact" class="contact" send-message-title="YesWash洗车客服">在线客服</button>
-        <image class="cs" src="/static/iconfont/cs.svg"/>
-      </movable-view>
-    </movable-area>-->
 
+    <!-- 站点列表区域(保留列表,移除标题) -->
+    <view class="station-section" :style="stationSectionStyle">
+      <scroll-view 
+        class="station-scroll" 
+        scroll-y="true"
+        :show-scrollbar="true"
+      >
+        <view class="station-list">
+          <WashStation 
+            v-for="item in state.stationList" 
+            :key="item.id" 
+            :item="item"
+          ></WashStation>
+          
+          <uv-empty 
+            v-if="!state.stationList || state.stationList.length === 0"
+            mode="list"
+            text="附近暂无站点"
+            :marginTop="60"
+          ></uv-empty>
+        </view>
+      </scroll-view>
+    </view>
 
+    <!-- 客服按钮 -->
     <custom-service></custom-service>
-    <!--    站点清单  end-->
-
 
-    <!--    停车券-->
-    <uv-popup ref="parking_popup_ref">
-      <view class="parking_box">
-        <text>长按识别二维码获取停车优惠</text>
-        <image show-menu-by-longpress src="/static/parking-qrcode.jpg"/>
+    <!-- 停车券弹窗 -->
+    <uv-popup ref="parking_popup_ref" mode="center" :round="16">
+      <view class="parking-popup">
+        <view class="popup-title">停车优惠</view>
+        <view class="popup-content">
+          <text class="popup-desc">长按识别二维码获取停车优惠</text>
+          <image 
+            class="qrcode-image" 
+            show-menu-by-longpress 
+            src="/static/parking-qrcode.jpg"
+          />
+        </view>
       </view>
     </uv-popup>
 
-    <!--    <cover-view class="login_bar">
-          <login-bar class="w100 text-center"></login-bar>
-        </cover-view>-->
-    <!--    <cover-view class="login_bar" v-show="!isLogin">-->
-    <!--    <login-bar class="w100 text-center" ></login-bar>-->
-    <!--    </cover-view>-->
+    <!-- 底部导航栏 -->
     <tab-bar :index="0"></tab-bar>
   </view>
 </template>
 
 <script setup lang="ts">
-import {nextTick, reactive, ref} from 'vue'
+import {computed, nextTick, reactive, ref} from 'vue'
 import {onHide, onLoad, onShow} from "@dcloudio/uni-app";
 import TabBar from "@/components/tab-bar/index.vue";
 import WashStation from "@/components/station/index.vue"
 import {get, post} from "@/utils/https";
 import {calcMapDistance} from "@/utils/common"
 import {checkLogin, fetchToken, loadUserInfo, tryLogin} from "@/utils/auth";
-import {rpxToPx} from "@/utils/device";
 
 const parking_popup_ref = ref();
 const isLogin = ref(false)
-const isDragging = ref(false)
-
-
-const change = () => {
-  console.log("change")
-}
+const statusBarHeight = ref(0)
+const navbarHeight = ref(0)
+const bannerHeight = ref(0)
+const menuHeight = ref(0)
 
 const initState = () => ({
   bannerList: [],
@@ -97,51 +144,49 @@ const initState = () => ({
     {name: "coupon", auth: false, title: "消费券", icon: '/static/iconfont/default/coupon.svg'},
     {name: "parking", auth: false, title: "停车券", icon: '/static/iconfont/default/parking.svg'},
   ],
-  qrcodeOption: {
-    style: 'round',
-    size: 230,
-    // 指定二维码前景,一般可在中间放logo
-    foregroundImageSrc: 'https://www.uvui.cn/common/logo.png'
-  },
-  customStyle: {
-    height: '180px',
-    width: '100%',
-  },
-  notice: '中秋佳节,全场8折,快来洗车吧!',
   stationList: [],
   location: {
     latitude: 0,
     longitude: 0,
   },
-  startAxis: {},
-  csAxis: {
-    right: '0rpx',
-    top: '200rpx'
-  },
-  areaStyle: {
-    "height": "100vh",
-    "width": "750rpx",
-    top: 0,
-    position: "fixed",
-
-  },
-  screenWidth: 350,
-  screenHeight: 1200
 })
 
 const state = reactive(initState())
 
+// 轮播图高度计算
+const bannerStyle = computed(() => {
+  const windowInfo = uni.getWindowInfo();
+  // 使用固定宽高比 16:9 或 2:1,确保各设备上一致
+  const height = windowInfo.windowWidth * 0.5; // 2:1 比例
+  bannerHeight.value = height;
+  return {
+    height: `${height}px`
+  }
+})
+
+// 计算站点列表区域的高度
+const stationSectionStyle = computed(() => {
+  const windowInfo = uni.getWindowInfo();
+  // 导航栏总高度 = 状态栏高度 + 导航内容高度(88rpx转px)
+  const navTotalHeight = statusBarHeight.value + (88 * windowInfo.windowWidth / 750);
+  // 轮播图高度
+  const bannerH = bannerHeight.value || 0;
+  // 快捷服务区域预估高度(卡片padding + 标题 + 图标 + 间距,约280rpx转px)
+  const menuH = 280 * windowInfo.windowWidth / 750;
+  // 底部tabbar高度(约100rpx转px)
+  const tabbarH = 100 * windowInfo.windowWidth / 750;
+  // 可用高度 = 窗口高度 - 固定区域高度
+  const availableHeight = windowInfo.windowHeight - navTotalHeight - bannerH - menuH - tabbarH;
+  
+  return {
+    height: `${availableHeight}px`
+  }
+})
+
 onLoad((e: any) => {
-  let height = uni.getWindowInfo().windowHeight;
-  // console.log(height, width, "screen")
-  state.screenWidth = uni.getWindowInfo().windowWidth;
-  state.screenHeight = uni.getWindowInfo().windowHeight;
-  // const bound = uni.getMenuButtonBoundingClientRect();
-  // width: 100%;height:170px;
-  state.customStyle = {
-    width: '100%',
-    height: `${(height - rpxToPx(60)) / 4}px`
-  };
+  // 获取状态栏高度
+  const systemInfo = uni.getSystemInfoSync();
+  statusBarHeight.value = systemInfo.statusBarHeight || 0;
 
   let token = fetchToken();
   if (token) {
@@ -149,14 +194,12 @@ onLoad((e: any) => {
     getApp<any>().globalData.isLogin = true;
 
     let gd = getApp<any>().globalData;
-    console.log(gd)
     if (!gd.user || !gd.user.id) {
       loadUserInfo();
     } else {
       isLogin.value = true;
     }
   } else {
-    //主动退出的不自动登录
     let manualLogout = getApp<any>().globalData.manualLogout;
     if (!manualLogout) {
       tryLogin().then(token => {
@@ -165,7 +208,6 @@ onLoad((e: any) => {
         isLogin.value = true;
       }).catch(e => {
         console.error(e)
-        gotoLogin()
       })
     }
   }
@@ -176,14 +218,6 @@ onLoad((e: any) => {
 })
 
 onShow(() => {
-  let height = uni.getWindowInfo().windowHeight;
-  // const bound = uni.getMenuButtonBoundingClientRect();
-  // width: 100%;height:170px;
-  state.customStyle = {
-    width: '100%',
-    height: `${(height - rpxToPx(60)) / 4}px`
-  };
-
   loadInitData()
 });
 
@@ -193,7 +227,6 @@ onHide(() => {
 
 
 const loadInitData = () => {
-  console.log("show index>>>>", isLogin.value, state.stationList, state.location)
   let locationData = getApp<any>().globalData.location;
   if (!locationData || !locationData.longitude) {
     loadCurrentLocation();
@@ -275,7 +308,7 @@ const handleMenuItemNative = (menu:any) => {
   } else {
     uni.showToast({
       icon: 'none',
-      title: '请期待',
+      title: '请期待',
     })
   }
 }
@@ -288,7 +321,7 @@ const loadCurrentLocation = () => {
     scope: 'scope.userLocation',
     success() {
       uni.getLocation({
-        type: 'gcj02', //返回可以用于uni.openLocation的经纬度
+        type: 'gcj02',
         success: res => {
           let location = {
             latitude: res.latitude,
@@ -296,7 +329,6 @@ const loadCurrentLocation = () => {
           }
           getApp<any>().globalData.location = location;
           state.location = location
-          console.log("loadCurrentLocation location", res)
           loadWashStationList();
         }
       });
@@ -306,7 +338,6 @@ const loadCurrentLocation = () => {
       console.log("authorize location fail", e)
     }
   })
-
 }
 
 const loadWashStationList = () => {
@@ -322,37 +353,14 @@ const loadWashStationList = () => {
   })
 }
 
-const handleNavMap = (station: any) => {
-  let location = JSON.parse(station.location)
-  uni.openLocation({
-    latitude: location.stationLat,
-    longitude: location.stationLng,
-    scale: 18,
-    name: station.stationName,
-    address: station.address,
-  });
+const handleOAerror = (e: any) => {
+  console.log("handleOAerror official-account", e)
 }
 
-const handleNavStation = (station: any) => {
-  getApp<any>().globalData.pageData = {station}
-  uni.navigateTo({
-    url: '/pages-wash/station/index?id=' + station.id
-  })
-  console.log(station)
+const handleOAload = (e: any) => {
+  console.log("handleOAload official-account", e)
 }
 
-
-
-const handleOAerror = (e) => {
-  console.log("handleOAerror official-account",e)
-}
-
-
-const handleOAload = (e) => {
-  console.log("handleOAload official-account",e)
-}
-
-
 </script>
 
 <style scoped lang="scss">
@@ -360,195 +368,251 @@ page {
   background: $uni-bg-color-page;
 }
 
-.content {
-  width: 100%;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  background-color: $uni-bg-color-page;
+.page-container {
+  min-height: 100vh;
+  background: linear-gradient(
+    180deg,
+    #FFE8E8 0%,
+    #FFF5F5 30%,
+    $uni-bg-color-page 60%
+  );
+  padding-bottom: 120rpx;
 }
 
-.logo {
-  height: 200rpx;
-  width: 200rpx;
-  margin: 200rpx auto 50rpx;
-}
-
-.menu-content {
-  width: 100%;
-  padding: 30rpx 20rpx;
-  background-color: $uni-bg-color-card;
-  margin-top: -20rpx;
-  border-radius: 20rpx 20rpx 0 0;
-  box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
+// 自定义导航栏
+.custom-navbar {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  z-index: 1000;
+  background: linear-gradient(
+    135deg,
+    #C6171E 0%,
+    #E84545 100%
+  );
+  box-shadow: 0 2rpx 12rpx rgba(198, 23, 30, 0.15);
+
+  .navbar-content {
+    height: 88rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    padding: 0 32rpx;
+
+    .navbar-title {
+      display: flex;
+      align-items: center;
+      gap: 12rpx;
+
+      .title-text {
+        color: white;
+        font-size: 36rpx;
+        font-weight: $uni-font-weight-semibold;
+        letter-spacing: 2rpx;
+      }
+    }
+  }
 }
 
-// 菜单按钮交互效果
-.uv-grid-item {
-  transition: all 0.3s ease;
-  cursor: pointer;
-  border-radius: 16rpx;
-  padding: 20rpx 0;
-  margin: 0 10rpx;
+// 优化后的轮播图区域
+.banner-wrapper {
+  margin-top: 88rpx;
+  position: relative;
 }
 
-.uv-grid-item:active {
-  transform: scale(0.95);
-  background-color: $uni-bg-color-hover;
-}
+.banner-container {
+  position: relative;
+  width: 100%;
+  overflow: hidden;
 
-.grid-text {
-  font-size: $uni-font-size-xs !important;
-  color: $uni-text-color-secondary;
-  margin-top: 12rpx;
-  transition: color 0.2s ease;
-}
+  .banner-swiper {
+    width: 100%;
+  }
 
-.uv-grid-item:active .grid-text {
-  color: $uni-color-primary;
-}
+  .banner-image {
+    width: 100%;
+    height: 100%;
+    display: block;
+  }
 
-.uv-grid-item image {
-  transition: all 0.2s ease;
+  // 渐变遮罩层,与下方内容过渡
+  .banner-overlay {
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    height: 60rpx;
+    background: linear-gradient(
+      to bottom,
+      rgba(255, 255, 255, 0),
+      rgba(255, 245, 245, 0.8)
+    );
+    pointer-events: none;
+    z-index: 1;
+  }
 }
 
-.uv-grid-item:active image {
-  transform: scale(0.9);
+// 公众号区域
+.official-account {
+  width: 100%;
+  margin: 20rpx 0;
 }
 
-.qrcode-content {
-  margin-top: 40rpx;
+// 优化后的菜单区域
+.menu-section {
   padding: 0 20rpx;
-  width: 100%;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  align-content: center;
-  justify-content: center;
-}
+  margin-bottom: 20rpx;
+}
+
+.menu-card {
+  background: white;
+  border-radius: 24rpx;
+  padding: 24rpx 20rpx;
+  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
+
+  .menu-header {
+    margin-bottom: 24rpx;
+
+    .menu-title {
+      display: flex;
+      align-items: center;
+      gap: 12rpx;
+      font-size: 30rpx;
+      font-weight: $uni-font-weight-semibold;
+      color: $uni-text-color;
+
+      .title-icon {
+        width: 6rpx;
+        height: 28rpx;
+        background: linear-gradient(
+          to bottom,
+          $uni-color-primary,
+          $uni-color-primary-light
+        );
+        border-radius: 3rpx;
+      }
+    }
+  }
 
-.gap {
-  width: 100%;
-  height: 20rpx;
-  background-color: $uni-bg-color-page;
-}
+  .menu-grid {
+    display: grid;
+    grid-template-columns: repeat(4, 1fr);
+    gap: 16rpx;
+  }
 
-.swiper-content {
-  width: 100%;
-  border-radius: 0 0 20rpx 20rpx;
-  overflow: hidden;
-  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
-}
+  .menu-item {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    gap: 12rpx;
+    padding: 16rpx 0;
+    border-radius: 16rpx;
+    transition: all 0.3s ease;
+    cursor: pointer;
+
+    &:active {
+      transform: scale(0.95);
+      background: $uni-bg-color-hover;
+    }
 
-// 轮播图样式增强
-.swiper-content swiper {
-  border-radius: 0 0 20rpx 20rpx;
-}
+    .menu-icon-wrapper {
+      width: 80rpx;
+      height: 80rpx;
+      background: linear-gradient(
+        135deg,
+        rgba(198, 23, 30, 0.08),
+        rgba(232, 69, 69, 0.05)
+      );
+      border-radius: 20rpx;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      box-shadow: 0 4rpx 12rpx rgba(198, 23, 30, 0.08);
+      transition: all 0.3s ease;
+    }
 
-.swiper-content swiper-item {
-  border-radius: 0 0 20rpx 20rpx;
-  overflow: hidden;
-  position: relative;
-}
+    &:active .menu-icon-wrapper {
+      transform: scale(0.9);
+      box-shadow: 0 2rpx 8rpx rgba(198, 23, 30, 0.12);
+    }
 
-// 轮播图点击效果
-.swiper-content swiper-item image {
-  transition: all 0.2s ease;
-  cursor: pointer;
-}
+    .menu-icon {
+      width: 48rpx;
+      height: 48rpx;
+    }
 
-.swiper-content swiper-item:active image {
-  transform: scale(0.98);
-  opacity: 0.95;
-}
+    .menu-title-text {
+      font-size: 24rpx;
+      color: $uni-text-color-secondary;
+      font-weight: 500;
+      transition: color 0.2s ease;
+    }
 
-.guide-content {
-  text-align: center;
+    &:active .menu-title-text {
+      color: $uni-color-primary;
+    }
+  }
 }
 
-.loginbar {
-  position: fixed;
-  bottom: 20rpx;
+// 站点列表区域(移除标题,保留列表)
+.station-section {
+  padding: 0 20rpx;
+  margin-bottom: 20rpx;
+  overflow: hidden;
 }
 
-.content_station {
-  padding: 0 20rpx 200rpx;
+.station-scroll {
   width: 100%;
-  box-sizing: border-box;
+  height: 100%;
 }
 
-.customer-service {
-  height: 100rpx;
-  width: 100rpx;
-
-  image {
-    width: 80rpx !important;
-    height: 80rpx !important;
-    z-index: 100;
-    position: absolute;
-    margin-top: -60rpx;
-  }
-
-  .contact {
-    opacity: 0;
-    z-index: 9999;
-  }
+.station-list {
+  display: flex;
+  flex-direction: column;
+  padding-bottom: 20rpx;
 }
 
-.mov-area {
-  pointer-events: none;
+// 停车券弹窗
+.parking-popup {
+  width: 600rpx;
+  background: white;
+  border-radius: 24rpx;
+  overflow: hidden;
 
-  .movable-view {
-    width: 100rpx !important;
-    height: 100rpx !important;
-    pointer-events: auto;
+  .popup-title {
+    background: linear-gradient(
+      135deg,
+      $uni-color-primary 0%,
+      $uni-color-primary-light 100%
+    );
+    color: white;
+    font-size: 32rpx;
+    font-weight: $uni-font-weight-semibold;
+    text-align: center;
+    padding: 32rpx;
   }
-}
 
-$all_width: 96rpx;
-$all_height: 96rpx;
-movable-area {
-  height: calc(100vh - 200rpx);
-  width: 750rpx;
-  top: 0;
-  position: fixed;
-  pointer-events: none;
-  movable-view {
-    width: $all_width;
-    height: $all_height;
-    pointer-events: auto;
-    image {
-      width: $all_width;
-      height: $all_height;
+  .popup-content {
+    padding: 40rpx;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    gap: 32rpx;
+
+    .popup-desc {
+      font-size: 28rpx;
+      color: $uni-text-color-secondary;
+      text-align: center;
+      line-height: 1.6;
     }
-  }
-}
 
-.parking_box {
-  width: 500rpx;
-  background-color: $uni-bg-color-card;
-  padding: 40rpx;
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
-  align-items: center;
-  border-radius: 16rpx;
-  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.15);
-  
-  text {
-    padding-bottom: 30rpx;
-    font-size: 16px;
-    color: $uni-text-color;
-    font-weight: 500;
-    text-align: center;
-    line-height: 1.5;
-  }
-  
-  image {
-    border-radius: 12rpx;
-    width: 420rpx;
-    height: 420rpx;
-    box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+    .qrcode-image {
+      width: 480rpx;
+      height: 480rpx;
+      border-radius: 16rpx;
+      box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
+    }
   }
 }
 </style>

+ 292 - 214
src/pages/user/index.vue

@@ -1,76 +1,99 @@
 <template>
-  <uv-navbar leftIcon="" title="我的" bg-color="#C6171E"></uv-navbar>
-  <view class="w100 bg" style="background-color:#C6171E "></view>
-  <!--  <image src="/static/user/user-bg.png" mode="widthFix" class="bg"/>-->
+  <view class="page-container">
+    <!-- 自定义导航栏 -->
+    <view class="custom-navbar" :style="{paddingTop: statusBarHeight + 'px'}">
+      <view class="navbar-content">
+        <view class="navbar-title">
+          <uv-icon name="account-fill" color="white" size="20"></uv-icon>
+          <text class="title-text">我的</text>
+        </view>
+      </view>
+    </view>
 
-  <block>
-    <view class="container" :style="containerStyle">
+    <!-- 页面内容区域 -->
+    <scroll-view class="content-scroll" scroll-y="true">
       <custom-service></custom-service>
-      <view class="header">
-        <view class="flex-center">
-          <image
-              src="/static/user/round.png"
-              mode="heightFix"
-              style="width: 120rpx;height: 120rpx"/>
+      
+      <!-- 用户信息与钱包合并卡片 -->
+      <view class="user-wallet-card">
+        <!-- 用户信息区域 -->
+        <view class="user-section">
+          <view class="user-avatar-wrapper">
+            <image class="user-avatar" src='/static/iconfont/me.svg'></image>
+          </view>
+          
+          <view class="user-info">
+            <view class="user-phone">{{ user.mobilePhone || '未登录' }}</view>
+            <view class="user-tip">欢迎使用Yeswash洗车</view>
+          </view>
         </view>
-        <view class="main">
-          <image
-              class="avatar"
-              src='/static/iconfont/me.svg'>
-          </image>
-          <view class="phone  fw-500">{{ user.mobilePhone }}</view>
-
-          <view class="money-box">
-            <view class="money" @click="toPage({path: '/pages-user/wallet/index'})">
-              <view class="money-left">
-                <uv-icon name="coupon" size="24" color="#C6171E"></uv-icon>
-                <!--              <image src="/static/iconfont/chongzhi.svg"  mode="widthFit"  style="width: 40rpx;height: 40rpx"></image>-->
-                <!--              <uv-icon name="red-packet" size="24" color="#C6171E"></uv-icon>-->
-                <view style="font-size: 16px;margin-left: 10rpx;">钱包 | 充值</view>
-              </view>
-
-              <view class="money-right">
-
-                <view class="money-right_balance"> ¥ {{ ((user.balance || 0) / 100).toFixed(2) }}</view>
-              </view>
-
+        
+        <!-- 分割线 -->
+        <view class="divider"></view>
+        
+        <!-- 钱包信息区域 -->
+        <view class="wallet-section" @click="toPage({path: '/pages-user/wallet/index'})">
+          <view class="wallet-header">
+            <view class="wallet-title">
+              <uv-icon name="bag" size="18" color="#C6171E"></uv-icon>
+              <text>我的钱包</text>
+            </view>
+            <view class="wallet-action">
+              <text class="action-text">充值</text>
+              <uv-icon name="arrow-right" size="12" color="#909399"></uv-icon>
+            </view>
+          </view>
+          
+          <view class="wallet-balance">
+            <text class="balance-label">账户余额</text>
+            <view class="balance-value">
+              <text class="balance-symbol">¥</text>
+              <text class="balance-amount">{{ ((user.balance || 0) / 100).toFixed(2) }}</text>
             </view>
           </view>
-
         </view>
       </view>
 
-      <view class="body">
-        <block v-for="(item, index) in menu" :key="index">
-          <view
-              class="menu-item"
-              @click="toPage(item)">
-            <view class="menu-item_left">
-              <image :src="item.icon"></image>
-              <view class="menu-item_left-title">{{ item.title }}</view>
-            </view>
-            <view class="menu-item_right">
-              <uv-icon name="arrow-right" size="16"></uv-icon>
+      <!-- 功能菜单列表 -->
+      <view class="menu-section">
+        <view class="section-title">
+          <view class="title-line"></view>
+          <text>功能服务</text>
+        </view>
+        
+        <view class="menu-list">
+          <view 
+            class="menu-item" 
+            v-for="(item, index) in menu" 
+            :key="index"
+            @click="toPage(item)"
+          >
+            <view class="menu-left">
+              <view class="menu-icon-box">
+                <image class="menu-icon" :src="item.icon" mode="aspectFit"></image>
+              </view>
+              <text class="menu-text">{{ item.title }}</text>
             </view>
+            <uv-icon name="arrow-right" size="16" color="#C0C4CC"></uv-icon>
           </view>
-        </block>
-
-        <view class="logout-btn" v-if="isLogin">
-          <view class="mt20 logout-btn-wrap" type="error" @click="logoutUser">退出登录</view>
         </view>
       </view>
-    </view>
-  </block>
-
-  <!--  <cover-view class="login_bar" v-if="!isLogin">
-      <login-bar class="w100 text-center"></login-bar>
-    </cover-view>-->
 
-  <!--  <view class="logout-btn">
-      <uv-button :custom-style="customStyle" type="error" @click="logoutUser">退出登录</uv-button>
-    </view>-->
-
-  <tab-bar :index="2"/>
+      <!-- 退出登录按钮 -->
+      <view class="logout-wrapper" v-if="isLogin">
+        <view class="logout-btn" @click="logoutUser">
+          <uv-icon name="error-circle" color="#DD524D" size="18"></uv-icon>
+          <text>退出登录</text>
+        </view>
+      </view>
+      
+      <!-- 底部占位 -->
+      <view style="height: 140rpx;"></view>
+    </scroll-view>
+
+    <!-- 底部导航栏 -->
+    <tab-bar :index="2"/>
+  </view>
 </template>
 
 <script setup lang="ts">
@@ -82,7 +105,7 @@ import {checkLogin, clearToken, loadUserInfo} from "@/utils/auth"
 import {get} from "@/utils/https";
 import {getServicePhone} from "@/utils/common";
 
-const containerStyle = ref({});
+const statusBarHeight = ref(0)
 const user = ref<any>({
   id: 0,
   avatar: "",
@@ -97,23 +120,11 @@ const menu = ref([
     path: "/pages-user/profile/index",
     icon: '/static/user/profile.png'
   },
-  /*  {
-      title: "我的卡包",
-      path: "/pages/coupon/index",
-      icon: '/static/user/coupon.png'
-    },*/
   {
     title: "我的订单",
     path: "/pages-order/list/index",
-
     icon: '/static/user/faq.png'
   },
-  /*  {
-      title: "我的收藏",
-      path: "/pages-user/fav/index",
-      icon: '/static/user/fav.png'
-    },*/
-
   {
     title: "联系我们",
     path: "/pages-user/contact/index",
@@ -196,11 +207,9 @@ const logoutUser = () => {
 };
 
 onLoad(() => {
-  uni.setNavigationBarTitle({title: '个人中心'})
-  const bound = uni.getMenuButtonBoundingClientRect();
-  containerStyle.value = {
-    top: `${bound.bottom + 10}px`,
-  };
+  // 获取状态栏高度
+  const systemInfo = uni.getSystemInfoSync();
+  statusBarHeight.value = systemInfo.statusBarHeight || 0;
 });
 
 const addListener = () => {
@@ -268,179 +277,248 @@ onHide(() => {
 })
 </script>
 
-<style lang="scss" scope>
+<style lang="scss" scoped>
 page {
-  background-color: #fafafa;
+  background: #f5f5f5;
 }
 
-.bg {
-  position: absolute;
-  left: 0;
-  top: 0;
-  width: 100%;
-  height: 460rpx;
+.page-container {
+  width: 100vw;
+  height: 100vh;
+  background: linear-gradient(180deg, #C6171E 0%, #E84545 25%, #f5f5f5 45%);
+  display: flex;
+  flex-direction: column;
 }
 
-.container {
-  position: absolute;
-  left: 0;
-  top: 0;
-  height: calc(100vh - 250rpx);
-  width: 100%;
-  overflow-y: hidden;
+// 自定义导航栏
+.custom-navbar {
+  position: relative;
+  z-index: 100;
+  
+  .navbar-content {
+    height: 88rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    
+    .navbar-title {
+      display: flex;
+      align-items: center;
+      gap: 12rpx;
+      
+      .title-text {
+        color: white;
+        font-size: 36rpx;
+        font-weight: 600;
+        letter-spacing: 2rpx;
+      }
+    }
+  }
 }
 
-.header {
-  //height: 400rpx;
+// 内容滚动区域
+.content-scroll {
+  flex: 1;
+  height: 100%;
   width: 100%;
-  flex-direction: column;
-
-  .main {
-    //height: 234rpx;
-    //padding: 60rpx auto;
-    background: rgba(254, 255, 255, 0.7);
-    border-radius: 40rpx 40rpx 0 0;
-    position: relative;
-    text-align: center;
-    z-index: 999;
+}
 
-    .avatar {
-      position: absolute;
-      left: 50%;
-      transform: translateX(-50%);
-      top: -90rpx;
-      width: 110rpx;
-      height: 110rpx;
-      border: 2rpx solid #ffffff;
-      //filter: drop-shadow(0px 4rpx 8rpx rgba(0, 24, 60, 0.1));
-      background-size: cover;
-      background-repeat: no-repeat;
-      border-radius: 50%;
+// 用户信息与钱包合并卡片
+.user-wallet-card {
+  margin: 30rpx 30rpx 24rpx;
+  background: white;
+  border-radius: 24rpx;
+  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
+  overflow: hidden;
+  
+  // 用户信息区域
+  .user-section {
+    padding: 32rpx;
+    display: flex;
+    align-items: center;
+    gap: 24rpx;
+    
+    .user-avatar-wrapper {
+      flex-shrink: 0;
+      
+      .user-avatar {
+        width: 88rpx;
+        height: 88rpx;
+        border-radius: 50%;
+        background: linear-gradient(135deg, rgba(198, 23, 30, 0.1), rgba(232, 69, 69, 0.05));
+        padding: 8rpx;
+        box-sizing: border-box;
+      }
     }
-
-    .phone {
-      padding-top: 20rpx;
-      //padding-top: 78rpx;
-      color: #000;
-      //padding: 30rpx auto;
-      font-size: 40rpx;
+    
+    .user-info {
+      flex: 1;
+      
+      .user-phone {
+        font-size: 32rpx;
+        font-weight: 600;
+        color: #303133;
+        margin-bottom: 8rpx;
+      }
+      
+      .user-tip {
+        font-size: 22rpx;
+        color: #909399;
+      }
     }
-
-    .money-box {
-      background: #EEB9BB;
-      padding: 60rpx 20rpx;
+  }
+  
+  // 分割线
+  .divider {
+    height: 1rpx;
+    background: #f5f5f5;
+    margin: 0 32rpx;
+  }
+  
+  // 钱包区域
+  .wallet-section {
+    padding: 28rpx 32rpx;
+    
+    .wallet-header {
       display: flex;
-      justify-content: center;
+      justify-content: space-between;
       align-items: center;
-      align-content: center;
-
-      .money {
-        //position: absolute;
-        //left: 0;
-        //bottom: 0;
-        width: 600rpx;
-        //height: 98rpx;
-        background: #fff;
-        border-radius: 120rpx;
-        //margin: 130rpx auto 40rpx auto;
-        //color: #000000;
-        padding: 20rpx;
-        font-size: 22px;
+      margin-bottom: 20rpx;
+      
+      .wallet-title {
         display: flex;
-        align-content: center;
         align-items: center;
-        justify-content: space-between;
-
-
-        &-left {
-          opacity: 1;
-          color: $uni-color-primary;
-          display: inline-flex;
-          align-items: flex-end;
-          font-size: 22px;
+        gap: 8rpx;
+        font-size: 26rpx;
+        font-weight: 600;
+        color: #303133;
+      }
+      
+      .wallet-action {
+        display: flex;
+        align-items: center;
+        gap: 4rpx;
+        
+        .action-text {
+          font-size: 22rpx;
+          color: #909399;
         }
-
-        &-right {
-          font-size: 22px;
-          opacity: 1;
-          color: $uni-color-primary;
-          display: inline-flex;
-          align-items: flex-end;
-
-          &_balance {
-            padding-left: 5px;
-            font-size: 26px;
-            font-weight: 600;
-            margin-right: 10px;
-          }
+      }
+    }
+    
+    .wallet-balance {
+      .balance-label {
+        font-size: 22rpx;
+        color: #909399;
+        margin-bottom: 8rpx;
+        display: block;
+      }
+      
+      .balance-value {
+        display: flex;
+        align-items: baseline;
+        gap: 6rpx;
+        
+        .balance-symbol {
+          font-size: 24rpx;
+          color: #C6171E;
+          font-weight: 500;
+        }
+        
+        .balance-amount {
+          font-size: 40rpx;
+          color: #C6171E;
+          font-weight: 600;
         }
       }
     }
-
   }
 }
 
-.body {
-  width: 100%;
-  background-color: #fff;
-  //border-top: 1px solid $uni-color-primary;
-  //padding: 0rpx 30rpx;
-
+// 菜单区域
+.menu-section {
+  margin: 0 30rpx 24rpx;
+  
+  .section-title {
+    display: flex;
+    align-items: center;
+    gap: 12rpx;
+    padding: 0 12rpx;
+    margin-bottom: 20rpx;
+    font-size: 28rpx;
+    font-weight: 600;
+    color: #303133;
+    
+    .title-line {
+      width: 6rpx;
+      height: 28rpx;
+      background: linear-gradient(to bottom, #C6171E, #E84545);
+      border-radius: 3rpx;
+    }
+  }
+  
+  .menu-list {
+    background: white;
+    border-radius: 24rpx;
+    overflow: hidden;
+    box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
+  }
+  
   .menu-item {
-    display: inline-flex;
+    display: flex;
     justify-content: space-between;
-    background-color: #fff;
-    height: 90rpx;
-    border-bottom: 1rpx solid rgba(0, 0, 0, 0.1);
     align-items: center;
-    width: 100%;
-
-    &_left {
+    padding: 28rpx 32rpx;
+    border-bottom: 1rpx solid #f5f5f5;
+    
+    &:last-child {
+      border-bottom: none;
+    }
+    
+    .menu-left {
       display: flex;
       align-items: center;
-      align-content: center;
-      margin-left: 20rpx;
-
-      image {
-        width: 42rpx;
-        height: 42rpx;
-        margin-right: 20rpx;
+      gap: 24rpx;
+      
+      .menu-icon-box {
+        width: 72rpx;
+        height: 72rpx;
+        background: linear-gradient(135deg, rgba(198, 23, 30, 0.08), rgba(232, 69, 69, 0.05));
+        border-radius: 16rpx;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        
+        .menu-icon {
+          width: 42rpx;
+          height: 42rpx;
+        }
       }
-
-      &-title {
-        font-size: 13px;
+      
+      .menu-text {
+        font-size: 28rpx;
+        color: #303133;
       }
     }
-
-    &_right {
-      text-align: right;
-      width: 60rpx;
-    }
-
-
-    &:last-child {
-      border-bottom: none;
-    }
   }
 }
 
-.logout-btn {
-  width: calc(100vw - 60rpx);
-  margin: 60rpx auto;
-
-  &-wrap {
-    height: 80rpx;
-    border-radius: 40rpx;
-    font-size: 28rpx;
-    margin: 20px auto;
-    width: 540rpx;
-    text-align: center;
-    background: #dd524d;
-    color: white;
+// 退出按钮
+.logout-wrapper {
+  margin: 40rpx 30rpx;
+  
+  .logout-btn {
     display: flex;
     align-items: center;
-    align-content: center;
     justify-content: center;
+    gap: 12rpx;
+    height: 88rpx;
+    background: white;
+    border-radius: 44rpx;
+    font-size: 28rpx;
+    color: #DD524D;
+    font-weight: 500;
+    box-shadow: 0 4rpx 20rpx rgba(221, 82, 77, 0.12);
   }
 }
 </style>