Pārlūkot izejas kodu

AI优化钱包页面

skyline 4 mēneši atpakaļ
vecāks
revīzija
d1d048559c
1 mainītis faili ar 434 papildinājumiem un 143 dzēšanām
  1. 434 143
      src/pages-user/wallet/index.vue

+ 434 - 143
src/pages-user/wallet/index.vue

@@ -1,62 +1,130 @@
 <template>
   <view class="page">
+    <!-- 优化后的钱包头部 -->
     <view class="wallet-header">
-      <view class="wallet-header_title">
-        <view class="wallet-header_title-left">
-          <uv-icon name="level" color="white" size="28"></uv-icon>
-          <text class="font16">我的钱包</text>
+      <view class="wallet-header_top">
+        <view class="wallet-header_title">
+          <uv-icon name="bag" color="white" size="24"></uv-icon>
+          <text class="wallet-title-text">我的钱包</text>
+        </view>
+        <view class="wallet-header_refund" @click="handleRefund">
+          <uv-icon name="kefu-ermai" color="#C6171E" size="16"></uv-icon>
+          <text>退款</text>
         </view>
-        <text class="wallet-header_title-refund" @click="handleRefund">退款</text>
       </view>
+      
       <view class="wallet-header_balance">
-        <text class="font18 mr10" style="vertical-align: top">¥</text>
-        <text style="font-size: 32px; line-height: 32px;font-weight: 600;">{{ ((account.balance || 0) / 100).toFixed(2) }}
-        </text>
+        <text class="balance-label">账户余额(元)</text>
+        <view class="balance-amount">
+          <text class="balance-symbol">¥</text>
+          <text class="balance-number">{{ ((account?.balance || 0) / 100).toFixed(2) }}</text>
+        </view>
       </view>
-      <view class="wallet-header_pounds">
-        <view>
-          <text>充值余额:</text>
-          <text>{{ (account.rechargeBalance / 100).toFixed(2) }}</text>
+      
+      <view class="wallet-header_detail">
+        <view class="detail-item">
+          <view class="detail-icon">
+            <uv-icon name="integral-fill" color="#FFB800" size="18"></uv-icon>
+          </view>
+          <view class="detail-info">
+            <text class="detail-label">充值余额</text>
+            <text class="detail-value">¥{{ ((account?.rechargeBalance || 0) / 100).toFixed(2) }}</text>
+          </view>
         </view>
-
-        <view>
-          <text>赠款余额:</text>
-          <text>{{ (account.grantsBalance / 100).toFixed(2) }}</text>
+        <view class="detail-divider"></view>
+        <view class="detail-item">
+          <view class="detail-icon">
+            <uv-icon name="gift-fill" color="#FF6B6B" size="18"></uv-icon>
+          </view>
+          <view class="detail-info">
+            <text class="detail-label">赠款余额</text>
+            <text class="detail-value">¥{{ ((account?.grantsBalance || 0) / 100).toFixed(2) }}</text>
+          </view>
         </view>
       </view>
     </view>
 
+    <!-- 优化后的交易记录区域 -->
     <view class="wallet-body">
-      <uv-tabs :list="tabs" :current="tab" @click="handleTabClick"></uv-tabs>
-
-      <uv-list>
-        <uv-list-item
-            clickable v-for="(item,index) in dataList" :key="index" @click="handleClickDetail(item)">
-          <template #default>
-            <view class="wallet-item">
-              <view class="wallet-item_left">
-                <view class="wallet-item_header">
-                  <view class="flex-inline">
-                    <text class="wallet-item_header-type">{{ fmtDictName('WalletDetail.type', item.type) }}</text>
-                    <uv-text class="ml10 wallet-item_header-status" style="margin-left: 10px;" plain :size="12"
-                             :type="item.status==0?'primary':(item.status==1?'success':'error')"
-                             :text="fmtDictName('WalletDetail.status', item.status)"></uv-text>
-                  </view>
-                  <text class="wallet-item_header-amt">{{ (item.amount / 100).toFixed(2) }}元</text>
-                </view>
-                <view class="wallet-item_body">
-                  <text class="wallet-item_body-order">{{ item.orderNo }}</text>
-                  <text class="wallet-item_body-time">{{ fmtDateTime(item.transactionTime) }}</text>
-                </view>
+      <view class="transaction-header">
+        <view class="transaction-title">
+          <uv-icon name="list" color="#303133" size="18"></uv-icon>
+          <text>交易记录</text>
+        </view>
+      </view>
+      
+      <view class="tabs-wrapper">
+        <uv-tabs 
+          :list="tabs" 
+          :current="tab" 
+          @click="handleTabClick"
+          activeColor="#C6171E"
+          :lineColor="'#C6171E'"
+          lineHeight="3"
+          lineWidth="20"
+          :bold="true"
+        ></uv-tabs>
+      </view>
+
+      <view class="transaction-list">
+        <view 
+          class="transaction-card" 
+          v-for="(item,index) in dataList" 
+          :key="index" 
+          @click="handleClickDetail(item)"
+        >
+          <view class="transaction-card_header">
+            <view class="transaction-type">
+              <view class="type-icon" :class="'type-icon-' + item.type">
+                <uv-icon 
+                  :name="getTypeIcon(item.type)" 
+                  color="white" 
+                  size="16"
+                ></uv-icon>
               </view>
-              <view class="wallet-item_right">
-                <uv-icon name="arrow-right" v-if="item.type===3"></uv-icon>
+              <text class="type-name">{{ fmtDictName('WalletDetail.type', item.type) }}</text>
+            </view>
+            <view class="transaction-amount" :class="getAmountClass(item.type)">
+              <text>{{ getAmountPrefix(item.type) }}{{ (item.amount / 100).toFixed(2) }}</text>
+            </view>
+          </view>
+          
+          <view class="transaction-card_body">
+            <view class="transaction-info">
+              <view class="info-item">
+                <text class="info-label">订单号</text>
+                <text class="info-value">{{ item.orderNo }}</text>
+              </view>
+              <view class="info-item">
+                <text class="info-label">时间</text>
+                <text class="info-value">{{ fmtDateTime(item.transactionTime) }}</text>
               </view>
             </view>
-          </template>
-        </uv-list-item>
-      </uv-list>
-      <uv-empty mode="order" v-if="!dataList||dataList.length===0" text="暂无数据" :marginTop="200"></uv-empty>
+            
+            <view class="transaction-status">
+              <uv-text 
+                plain 
+                :size="12"
+                :type="item.status==0?'primary':(item.status==1?'success':'error')"
+                :text="fmtDictName('WalletDetail.status', item.status)"
+              ></uv-text>
+              <uv-icon 
+                name="arrow-right" 
+                v-if="item.type===3" 
+                color="#C0C4CC" 
+                size="16"
+              ></uv-icon>
+            </view>
+          </view>
+        </view>
+      </view>
+      
+      <uv-empty 
+        mode="order" 
+        v-if="!dataList||dataList.length===0" 
+        text="暂无交易记录" 
+        :marginTop="100"
+      ></uv-empty>
     </view>
 
     <view class="wallet-bottom">
@@ -78,7 +146,11 @@ import {body, get} from "@/utils/https";
 import {checkLogin} from "@/utils/auth";
 import {fmtDictName, fmtDateTime} from "@/utils/common";
 
-const account = ref();
+const account = ref({
+  balance: 0,
+  rechargeBalance: 0,
+  grantsBalance: 0
+});
 
 const dataList = ref([])
 const tab = ref(0);
@@ -110,6 +182,26 @@ const handleRefund = () => {
   // to(`/pages-user/wallet/refund`)
 }
 
+// 获取交易类型图标
+const getTypeIcon = (type: number) => {
+  const iconMap: Record<number, string> = {
+    1: 'integral-fill',  // 充值
+    2: 'red-packet', // 退款
+    3: 'shopping-cart-fill', // 消费
+  }
+  return iconMap[type] || 'list'
+}
+
+// 获取金额样式类
+const getAmountClass = (type: number) => {
+  return type === 1 || type === 2 ? 'amount-positive' : 'amount-negative'
+}
+
+// 获取金额前缀
+const getAmountPrefix = (type: number) => {
+  return type === 1 || type === 2 ? '+¥' : '-¥'
+}
+
 
 onLoad((options: any) => {
   if (options.tab) {
@@ -167,158 +259,357 @@ const handleClickDetail = (walletDetail: any) => {
 
 <style lang="scss">
 .page {
-  height: 100vh;
+  min-height: 100vh;
   width: 100vw;
   background: linear-gradient(
-          180deg,
-          #e0ebff 0%,
-          rgba(255, 255, 255, 0) 60.13%
+    180deg,
+    #FFE8E8 0%,
+    #FFF5F5 40%,
+    #FFFFFF 100%
   );
   display: flex;
   flex-direction: column;
+  padding-bottom: 140rpx;
 
-
+  // 优化后的钱包头部样式
   .wallet-header {
-    border-radius: 20rpx;
-    background-color: $uni-color-primary;
+    background: linear-gradient(
+      135deg,
+      #C6171E 0%,
+      #E84545 100%
+    );
     margin: 20rpx;
-    display: flex;
-    flex-direction: column;
-    padding: 20rpx;
+    border-radius: 24rpx;
+    padding: 32rpx 28rpx;
+    box-shadow: 0 8rpx 24rpx rgba(198, 23, 30, 0.25);
+    position: relative;
+    overflow: hidden;
+
+    // 装饰性背景
+    &::before {
+      content: '';
+      position: absolute;
+      top: -50rpx;
+      right: -50rpx;
+      width: 200rpx;
+      height: 200rpx;
+      background: rgba(255, 255, 255, 0.1);
+      border-radius: 50%;
+      z-index: 0;
+    }
 
-    &_title {
-      display: inline-flex;
+    &::after {
+      content: '';
+      position: absolute;
+      bottom: -80rpx;
+      left: -80rpx;
+      width: 260rpx;
+      height: 260rpx;
+      background: rgba(255, 255, 255, 0.08);
+      border-radius: 50%;
+      z-index: 0;
+    }
+
+    // 顶部标题栏
+    &_top {
+      display: flex;
       justify-content: space-between;
-      color: whitesmoke;
+      align-items: center;
+      margin-bottom: 32rpx;
+      position: relative;
+      z-index: 1;
+    }
 
-      &-left {
-        display: inline-flex;
-        align-items: center;
-        align-content: center;
-        color: whitesmoke;
+    &_title {
+      display: flex;
+      align-items: center;
+      gap: 12rpx;
+
+      .wallet-title-text {
+        color: white;
+        font-size: 32rpx;
+        font-weight: $uni-font-weight-semibold;
+        letter-spacing: 1rpx;
       }
+    }
 
-      &-refund {
-        color: $uni-color-primary;
-        padding: 6rpx 28rpx;
-        font-size: 26rpx;
-        border-radius: 14px;
-        background-color: #fff;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        align-content: center;
+    &_refund {
+      display: flex;
+      align-items: center;
+      gap: 6rpx;
+      background-color: white;
+      color: $uni-color-primary;
+      padding: 10rpx 24rpx;
+      border-radius: 32rpx;
+      font-size: 24rpx;
+      font-weight: 500;
+      box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+      transition: all 0.3s ease;
+
+      &:active {
+        transform: scale(0.95);
+        opacity: 0.9;
       }
     }
 
+    // 余额显示
     &_balance {
-      display: inline-flex;
-      color: white;
-      align-content: center;
-      margin-top: 40rpx;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      margin-bottom: 28rpx;
+      position: relative;
+      z-index: 1;
+
+      .balance-label {
+        color: rgba(255, 255, 255, 0.9);
+        font-size: 24rpx;
+        margin-bottom: 12rpx;
+        letter-spacing: 1rpx;
+      }
+
+      .balance-amount {
+        display: flex;
+        align-items: baseline;
+        
+        .balance-symbol {
+          color: white;
+          font-size: 36rpx;
+          font-weight: 600;
+          margin-right: 8rpx;
+        }
+
+        .balance-number {
+          color: white;
+          font-size: 72rpx;
+          font-weight: 700;
+          line-height: 1;
+          letter-spacing: 2rpx;
+        }
+      }
     }
 
-    &_pounds {
-      margin-top: 20rpx;
-      display: inline-flex;
-      align-content: center;
+    // 余额详情
+    &_detail {
+      display: flex;
+      justify-content: center;
       align-items: center;
-      color: white;
-      justify-content: space-between;
+      background: rgba(255, 255, 255, 0.2);
+      border-radius: 16rpx;
+      padding: 24rpx 20rpx;
+      backdrop-filter: blur(10px);
+      position: relative;
+      z-index: 1;
+
+      .detail-item {
+        flex: 1;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        gap: 12rpx;
+
+        .detail-icon {
+          width: 44rpx;
+          height: 44rpx;
+          background: white;
+          border-radius: 50%;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
+        }
+
+        .detail-info {
+          display: flex;
+          flex-direction: column;
+          align-items: center;
+          gap: 6rpx;
+
+          .detail-label {
+            color: rgba(255, 255, 255, 0.85);
+            font-size: 22rpx;
+            text-align: center;
+          }
+
+          .detail-value {
+            color: white;
+            font-size: 28rpx;
+            font-weight: 600;
+            text-align: center;
+          }
+        }
+      }
+
+      .detail-divider {
+        width: 2rpx;
+        height: 60rpx;
+        background: rgba(255, 255, 255, 0.3);
+        margin: 0 20rpx;
+      }
     }
   }
 
+  // 优化后的交易记录区域
   .wallet-body {
     flex: 1;
-    overflow-y: scroll;
-    overflow-x: hidden;
-    margin: 20rpx 20rpx 60rpx 20rpx;
-
+    display: flex;
+    flex-direction: column;
+    padding: 0 20rpx;
 
-    .wallet-item {
-      display: inline-flex;
-      //flex-direction: column;
-      padding: 14rpx;
-      border-radius: 8rpx;
-      margin: 10rpx 16 prx 10rpx 10rpx;
+    .transaction-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 20rpx;
 
+      .transaction-title {
+        display: flex;
+        align-items: center;
+        gap: 12rpx;
+        font-size: 32rpx;
+        font-weight: $uni-font-weight-semibold;
+        color: $uni-text-color;
+      }
+    }
 
-      &_left {
-        flex: 1;
-        flex-direction: column;
+    .tabs-wrapper {
+      background: white;
+      border-radius: 16rpx;
+      padding: 10rpx 0;
+      margin-bottom: 20rpx;
+      box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
+    }
 
-        .wallet-item_header {
-          width: 100%;
-          display: inline-flex;
-          flex-wrap: nowrap;
-          justify-content: space-between;
+    .transaction-list {
+      display: flex;
+      flex-direction: column;
+      gap: 20rpx;
+    }
 
-          &-type {
-            font-weight: 500;
-            font-size: 16px;
-            margin-right: 15rpx;
-          }
+    .transaction-card {
+      background: white;
+      border-radius: 16rpx;
+      padding: 28rpx 24rpx;
+      box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
+      transition: all 0.3s ease;
 
+      &:active {
+        transform: scale(0.98);
+        box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.08);
+      }
 
-          &-status {
-            font-size: 12px;
-            margin-left: 6px;
-            border: 1px solid $uni-color-primary;
-            border-radius: 2rpx;
-            transform: scale(0.8);
+      &_header {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 20rpx;
+        padding-bottom: 16rpx;
+        border-bottom: 1px solid $uni-border-color-light;
+
+        .transaction-type {
+          display: flex;
+          align-items: center;
+          gap: 16rpx;
+
+          .type-icon {
+            width: 48rpx;
+            height: 48rpx;
+            border-radius: 50%;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
+
+            &-1 {
+              background: linear-gradient(135deg, #67C23A, #85CE61);
+            }
+
+            &-2 {
+              background: linear-gradient(135deg, #E6A23C, #F0B668);
+            }
+
+            &-3 {
+              background: linear-gradient(135deg, #C6171E, #E84545);
+            }
           }
 
-          &-amt {
-            font-weight: 500;
-            font-size: 17px;
+          .type-name {
+            font-size: 30rpx;
+            font-weight: $uni-font-weight-semibold;
+            color: $uni-text-color;
           }
         }
 
-        .wallet-item_body {
-          width: 100%;
-          padding: 10rpx 0;
-          display: inline-flex;
-          justify-content: space-between;
+        .transaction-amount {
+          font-size: 40rpx;
+          font-weight: 700;
+          
+          &.amount-positive {
+            color: #67C23A;
+          }
 
-          &-order, &-time {
-            font-size: 12px;
-            color: $uni-color-subtitle
+          &.amount-negative {
+            color: #FA436A;
           }
         }
       }
 
-      &_right {
-        width: 42rpx;
+      &_body {
         display: flex;
+        justify-content: space-between;
         align-items: center;
-        align-content: center;
-        justify-content: center;
-      }
 
+        .transaction-info {
+          flex: 1;
+          display: flex;
+          flex-direction: column;
+          gap: 12rpx;
+
+          .info-item {
+            display: flex;
+            align-items: center;
+            gap: 16rpx;
+
+            .info-label {
+              font-size: 24rpx;
+              color: $uni-text-color-tertiary;
+              width: 80rpx;
+            }
+
+            .info-value {
+              font-size: 24rpx;
+              color: $uni-text-color-secondary;
+              flex: 1;
+              word-break: break-all;
+            }
+          }
+        }
+
+        .transaction-status {
+          display: flex;
+          flex-direction: column;
+          align-items: center;
+          gap: 8rpx;
+        }
+      }
     }
   }
 
+  // 底部充值按钮
   .wallet-bottom {
-    /*width: 100%;
-    height: 46px;*/
     width: calc(100vw - 40rpx);
     position: fixed;
     bottom: 30rpx;
     left: 20rpx;
-  }
-
-}
-
-
-.arrow-hide {
-  :deep(.uv-list-item .uv-icon) {
-    visibility: hidden !important;
-  }
-}
-
-.arrow-hide {
-  .uv-icon {
-    visibility: hidden !important;
+    z-index: 100;
+    
+    :deep(.uv-button) {
+      box-shadow: 0 8rpx 20rpx rgba(198, 23, 30, 0.3);
+      font-size: 32rpx;
+      font-weight: $uni-font-weight-semibold;
+      height: 88rpx;
+    }
   }
 }
 </style>