From 349c48e168b9f2580334422228acde7d1b21bede Mon Sep 17 00:00:00 2001
From: 李凌 <344137771@qq.com>
Date: Fri, 05 Jun 2026 11:19:15 +0800
Subject: [PATCH] 1

---
 src/views/cryptos/loan/index.vue |  610 +++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 389 insertions(+), 221 deletions(-)

diff --git a/src/views/cryptos/loan/index.vue b/src/views/cryptos/loan/index.vue
index 7a4c9d7..a1fc9d9 100644
--- a/src/views/cryptos/loan/index.vue
+++ b/src/views/cryptos/loan/index.vue
@@ -1,239 +1,213 @@
 <template>
   <div id="cryptos">
-    <div class="loan">
+    <div class="loan-page">
       <assets-head :title="$t('助力贷')">
         <div class="right flex items-center">
-          <img src="@/assets/image/loan/rule.png" alt="rule-img" class="w-50 h-50 mr-20"
+          <img src="@/assets/image/loan/rule.png" alt="rule-img" class="head-icon mr-20"
             @click="$router.push('/cryptos/loanRule')" />
-          <img src="@/assets/image/loan/history.png" alt="exchange-img" class="w-50 h-50"
+          <img src="@/assets/image/loan/history.png" alt="history-img" class="head-icon"
             @click="$router.push('/cryptos/loanHistory')" />
         </div>
       </assets-head>
 
-      <!--   container -->
-      <div class="container px-32">
-        <!--      title-->
-        <div class="py-30">
-          <span style="color: #E35461;">{{ this.$t('经过平台审核,您可向平台申请一笔借款!') }}</span>
+      <div class="loan-body">
+        <!-- 额度展示 -->
+        <div class="hero-card">
+          <div class="hero-badge">{{ $t('最高可借') }}</div>
+          <div class="hero-amount">
+            <span class="amount-num">{{ formatNum(loanData.maxQuota) }}</span>
+            <span class="amount-unit">USDT</span>
+          </div>
+          <p class="hero-tip">{{ $t('经过平台审核,您可向平台申请一笔借款!') }}</p>
         </div>
-        <!--    list  -->
-        <div class="loanList">
-          <div class="flex justify-between py-30 border-b-color">
-            <div>
-              <span class="grayText">{{ $t('期望借款金额') }}</span>
-            </div>
-            <div class="flex align-center">
-              <!--            <input class="font-600 textColor border-none text-right mr-14 mainBackground" v-model="loanAmount"  disabled="disabled" @input="inputAmunt" />-->
-              <span class="mr-14 font-600 textColor">{{ loanData.maxQuota || 0 }}</span>
-              <span class="font-600 textColor">USDT</span>
-            </div>
-          </div>
-          <div class="flex justify-between py-30 border-b-color">
-            <div>
-              <span class="grayText">{{ $t('还款周期') }}</span>
-            </div>
-            <div class="flex align-center">
-              <!--            <div class="font-600 textColor relative">-->
-              <div class="font-600 mr-14 textColor relative" @click="isSelectDay = !isSelectDay">
-                <span>{{ loanData.term }} {{ $t('天') }}</span>
-                <!--              <div class="selectDay"  v-show="isSelectDay">-->
-                <!--                <div class="mb-20 border-b-white" v-for="(s,index) in selectDayList" :key="index"  @click="selectDay(s)">-->
-                <!--                  <span>{{s}}</span>-->
-                <!--                </div>-->
-                <!--              </div>-->
-              </div>
-              <div class="w-24 h-24">
-                <img src="@/assets/image/loan/right.png" alt="right-img" class="w-full">
-              </div>
-            </div>
-          </div>
-          <div class="flex justify-between py-30 border-b-color">
-            <div>
-              <span class="grayText">{{ $t('日利率') }}</span>
-            </div>
-            <div class="flex align-center">
-              <span class="font-600 textColor">{{ loanData.dailyRate * 1 * 100 || 0 }}%</span>
-            </div>
-          </div>
-          <div class="flex justify-between py-30 border-b-color">
-            <div>
-              <span class="grayText">{{ $t('还款方式') }}</span>
-            </div>
-            <div class="flex align-center">
-              <span class="font-600 textColor text-right">{{ $t('到期一次还款') }}</span>
-            </div>
-          </div>
-          <div class="flex justify-between py-30 border-b-color">
-            <div>
-              <span class="grayText">{{ $t('利息') }}</span>
-            </div>
-            <div class="flex align-center">
-              <!--            借款金额*日利率*借款天数-->
-              <!-- <span class="font-600 textColor">{{$bigDecimal.multiply(+loanData.maxQuota , +loanData.dailyRate) * +this.loanData.term || 0 }} USDT</span> -->
-              <span class="font-600 textColor">{{ (+loanData.maxQuota, +loanData.dailyRate) * +this.loanData.term || 0 }}
-                USDT</span>
-            </div>
-          </div>
-          <div class="flex justify-between py-30 border-b-color">
-            <div>
-              <span class="grayText">{{ $t('放款机构') }}</span>
-            </div>
-            <div class="flex align-center">
-              <span class="font-600 textColor">{{ loanData.lendingName }}</span>
-            </div>
-          </div>
-        </div>
-        <!--      上传区域-->
-        <div class="uploadImg">
-          <div class="mb-40 textColor">
-            <span>{{ $t('信用放款(请确保图片清晰可见)') }}</span>
-          </div>
-          <div class="upload">
-            <div class="flex mt-33 mb-80 justify-between">
-              <div class="flex-1 flex flex-col text-center justify-center items-center">
-                <div class="upload-wrap">
-                  <!--                    <img src="@/assets/image/kyc/0.png" alt="" class="w-full"-->
-                  <!--                         v-if="[1, 2].includes(status) && frontFile.length === 0" />-->
-                  <van-uploader v-model="frontFile" multiple :max-count="1" :disabled="isUpload" :after-read="afterRead"
-                    @click-upload="onClickUpload('frontFile')" />
-                </div>
-                <div class="mt-32 font-26 h-20" style="color:#868D9A;">{{ $t('证件正面') }}</div>
-              </div>
-              <div class="flex-1 flex flex-col text-center justify-center items-center">
-                <div class="upload-wrap">
-                  <!--                    <img src="@/assets/image/kyc/1.png" alt="" class="w-full"-->
-                  <!--                         v-if="[1, 2].includes(status) && reverseFile.length === 0" />-->
-                  <van-uploader v-model="reverseFile" multiple :max-count="1" :disabled="isUpload" :after-read="afterRead"
-                    @click-upload="onClickUpload('reverseFile')" />
-                </div>
-                <div class="mt-32 font-26 h-20" style="color:#868D9A;">{{ $t('证件反面') }}</div>
-              </div>
-            </div>
-            <div class="flex mt-33 mb-80 justify-between">
-              <div class="flex-1 flex flex-col text-center justify-center items-center">
-                <div class="upload-wrap">
-                  <!--                    <img src="@/assets/image/kyc/2.png" alt="" class="w-full"-->
-                  <!--                         v-if="[1, 2].includes(status) && fileList.length === 0" />-->
-                  <van-uploader v-model="fileList" multiple :max-count="1" :disabled="isUpload" :after-read="afterRead"
-                    @click-upload="onClickUpload('fileList')" />
-                </div>
-                <div class="mt-32 font-26 h-20" style="color:#868D9A;">{{ $t('手持证件照') }}</div>
-              </div>
-              <div class="flex-1 flex flex-col text-center justify-center items-center">
-                <div class="upload-wrap">
-                  <img src="@/assets/image/loan/handId.png" alt="" class="w-full" />
-                </div>
-                <div class="mt-32 font-26 h-20" style="color:#868D9A;">{{ $t('拍摄示例') }}</div>
-              </div>
+
+        <!-- 期限选择 -->
+        <div class="section-card">
+          <div class="section-title">{{ $t('选择借款期限') }}</div>
+          <div class="term-list">
+            <div
+              v-for="item in loanDeployList"
+              :key="item.uuid || item.id || item.term"
+              class="term-item"
+              :class="{ active: isSamePlan(item) }"
+              @click="selectDay(item)"
+            >
+              <span class="term-days">{{ item.term }}</span>
+              <span class="term-unit">{{ $t('天') }}</span>
             </div>
           </div>
         </div>
 
-        <!--      确认按钮-->
-        <div class="confirmBtn btnMain w-full py-30 text-center text-white font-400 font-32" @click="submit()">
-          <span>{{ $t('确定') }}</span>
+        <!-- 方案详情 -->
+        <div class="section-card">
+          <div class="section-title">{{ $t('借款方案') }}</div>
+          <div class="info-grid">
+            <div class="info-row">
+              <span class="info-label">{{ $t('期望借款金额') }}</span>
+              <span class="info-value highlight">{{ formatNum(loanData.maxQuota) }} USDT</span>
+            </div>
+            <div class="info-row">
+              <span class="info-label">{{ $t('还款周期') }}</span>
+              <span class="info-value">{{ loanData.term || 0 }} {{ $t('天') }}</span>
+            </div>
+            <div class="info-row">
+              <span class="info-label">{{ $t('日利率') }}</span>
+              <span class="info-value">{{ dailyRatePercent }}%</span>
+            </div>
+            <div class="info-row">
+              <span class="info-label">{{ $t('预计总利息') }}</span>
+              <span class="info-value accent">{{ totalInterest }} USDT</span>
+            </div>
+            <div class="info-row">
+              <span class="info-label">{{ $t('还款方式') }}</span>
+              <span class="info-value">{{ $t('到期一次还款') }}</span>
+            </div>
+            <div class="info-row">
+              <span class="info-label">{{ $t('放款机构') }}</span>
+              <span class="info-value">{{ loanData.lendingName || '-' }}</span>
+            </div>
+          </div>
+        </div>
+
+        <!-- 证件上传 -->
+        <div class="section-card upload-section">
+          <div class="section-title">{{ $t('身份认证') }}</div>
+          <p class="upload-tip">{{ $t('信用放款(请确保图片清晰可见)') }}</p>
+          <div class="upload-grid">
+            <div class="upload-item">
+              <div class="upload-wrap">
+                <van-uploader
+                  v-model="frontFile"
+                  multiple
+                  :max-count="1"
+                  :deletable="!isUpload"
+                  :disabled="isUpload"
+                  :after-read="afterRead"
+                  @click-upload="onClickUpload('frontFile')"
+                />
+              </div>
+              <span class="upload-label">{{ $t('credentFront') }}</span>
+            </div>
+            <div class="upload-item">
+              <div class="upload-wrap">
+                <van-uploader
+                  v-model="reverseFile"
+                  multiple
+                  :max-count="1"
+                  :deletable="!isUpload"
+                  :disabled="isUpload"
+                  :after-read="afterRead"
+                  @click-upload="onClickUpload('reverseFile')"
+                />
+              </div>
+              <span class="upload-label">{{ $t('credentObverse') }}</span>
+            </div>
+          </div>
         </div>
       </div>
-      <van-popup v-model:show="isSelectDay" position="bottom" :round="true">
-        <ul class="bg-white">
-          <li v-for="(day, index) in loanDeployList" class="text-center py-30" :key="index" @click="selectDay(day)">
-            <span>{{ day.term }}</span>
-          </li>
-        </ul>
-      </van-popup>
+
+      <div class="submit-bar">
+        <button class="submit-btn" :disabled="isUpload" @click="submit">
+          {{ $t('提交申请') }}
+        </button>
+      </div>
     </div>
   </div>
 </template>
 
 <script>
 import AssetsHead from "@/components/Transform/assets-head/index.vue";
-import { Popup, Uploader, showToast } from "vant";
-import { _uploadImage, _getLoan, _loanApply } from "@/service/fund.api";
-// import {debounce} from "@/utils/utis";
+import { Uploader, showToast } from "vant";
+import { _getLoan, _loanApply } from "@/service/fund.api";
+import { _uploadImage } from "@/service/upload.api";
 
 export default {
   name: "loanIndex",
   components: {
     AssetsHead,
     [Uploader.name]: Uploader,
-    [Popup.name]: Popup,
+  },
+  computed: {
+    dailyRatePercent() {
+      const rate = Number(this.loanData.dailyRate) || 0;
+      return (rate * 100).toFixed(2);
+    },
+    totalInterest() {
+      const quota = Number(this.loanData.maxQuota) || 0;
+      const rate = Number(this.loanData.dailyRate) || 0;
+      const term = Number(this.loanData.term) || 0;
+      return (quota * rate * term).toFixed(2);
+    },
   },
   methods: {
+    formatNum(val) {
+      const n = Number(val) || 0;
+      return n.toLocaleString(undefined, { maximumFractionDigits: 2 });
+    },
+    isSamePlan(item) {
+      const key = item.uuid || item.id || item.term;
+      const cur = this.loanData.uuid || this.loanData.id || this.loanData.term;
+      return key === cur;
+    },
     getLoan() {
       _getLoan().then(data => {
-        this.loanDeployList = data
-        this.loanDeployList.sort((a, b) => {
-          return +a.term - +b.term
-        })
-        this.loanData = this.loanDeployList[0]
-      })
+        this.loanDeployList = (data || []).sort((a, b) => +a.term - +b.term);
+        if (this.loanDeployList.length) {
+          this.loanData = this.loanDeployList[0];
+        }
+      });
     },
     submit() {
-      // console.log('this.frontFile',this.frontFile)
-      if (!this.frontFile.length || !this.reverseFile.length || !this.fileList.length) {
-        showToast(this.$t('请上传完整证件信息'))
-        return
+      if (!this.frontFile.length || !this.reverseFile.length) {
+        showToast(this.$t('请上传证件正反面'));
+        return;
+      }
+      if (!this.frontFile[0].resURL || !this.reverseFile[0].resURL) {
+        showToast(this.$t('uploading'));
+        return;
       }
       _loanApply({
-        ...this.loanData,
-        // term:this.loanData.term,
-        quota: this.loanData.maxQuota,//借贷金额 取max
-        // dailyRate: this.loanData.dailyRate,
-        // lendingInstitution:this.loanData.lendingInstitution,//放款机构名字
-        // lendingName:this.loanData.lendingName,
-        // repayment:this.loanData.repayment,//还款方式
-        // repayCycle:this.loanData.repayCycle, //还款日期
+        uuid: this.loanData.uuid || this.loanData.id,
+        quota: this.loanData.maxQuota,
         symbol: 'USDT',
         frontFile: this.frontFile[0].resURL,
         reverseFile: this.reverseFile[0].resURL,
-        fileList: this.fileList[0].resURL,
-      }).then(res => {
-        // console.log('res',res)
-        this.$router.push('/cryptos/loanHistory')
+      }).then(() => {
+        showToast(this.$t('提交成功'));
+        this.$router.push('/cryptos/loanHistory');
       }).catch(err => {
-        showToast(this.$t(err.msg))
-      })
+        showToast(err.msg || this.$t('提交失败'));
+      });
     },
-    // //防抖
-    // inputAmunt(){
-    //   this.loanAmount = this.loanAmount.replace(/[^0-9]/g, '')
-    //   this.debounceFn()
-    // },
-    // debounceFn: debounce(function () {
-    //   this.getInterest()
-    // }, 500),
-    // getInterest(){
-    //   this.interest = +this.loanAmount * +this.loanRate
-    // },
     selectDay(data) {
-      this.loanData = data
-      // this.getInterest()
-      this.isSelectDay = false
+      this.loanData = data;
     },
     onClickUpload(type) {
-      this.curFile = type
+      this.curFile = type;
     },
-    afterRead(file) { /// 处理文件
-      // console.log(file)
-      file.status = 'uploading'
-      file.message = this.$t('上传中...')
-      this.isUpload = true
+    afterRead(file) {
+      file.status = 'uploading';
+      file.message = this.$t('uploading');
+      this.isUpload = true;
       _uploadImage(file).then(data => {
         file.status = 'success';
-        file.message = this.$t('上传成功');
-        file.resURL = data
-        this[this.curFile] = [file]
-        this.isUpload = false
-      }).catch(err => {
+        file.message = this.$t('uploadSuccess');
+        file.resURL = data;
+        if (this.curFile === 'frontFile') {
+          this.frontFile = [file];
+        } else {
+          this.reverseFile = [file];
+        }
+        this.isUpload = false;
+      }).catch(() => {
         file.status = 'failed';
-        file.message = this.$t('图片上传失败');
-        this.isUpload = false
-      })
+        file.message = this.$t('uploadFailed');
+        this.isUpload = false;
+      });
     },
   },
   mounted() {
-    this.getLoan()
-    // this.getInterest()
+    this.getLoan();
   },
   data() {
     return {
@@ -241,65 +215,259 @@
       loanDeployList: [],
       frontFile: [],
       reverseFile: [],
-      fileList: [],
       curFile: 'frontFile',
-      // resultArr: ['small-success_' + this.$t('已申请未审核'), 'identifing_' + this.$t('审核中'), 'small-success_' + this.$t('审核通过'), 'icon-close_' + this.$t('审核未通过')], // 0 好像是未提交
-      // status:'',
-      isSelectDay: false,
       isUpload: false,
-    }
-  }
-}
+    };
+  },
+};
 </script>
 
 <style scoped lang="scss">
 @import "@/assets/init.scss";
+
 #cryptos {
-  .loan {
-    width: 100%;
+  .loan-page {
+    min-height: 100vh;
+    padding-bottom: 160px;
     box-sizing: border-box;
   }
 
-  .uploadImg {
-    margin-top: 60px;
+  .head-icon {
+    width: 50px;
+    height: 50px;
+  }
 
-    .upload-wrap {
-      width: 356px;
-      height: 288px;
-      display: flex;
-      justify-content: center;
-      align-items: center;
+  .loan-body {
+    padding: 24px 32px 0;
+  }
 
-      ::v-deep .van-uploader__upload {
-        width: 356px !important;
-        height: 288px !important;
-      }
+  .hero-card {
+    padding: 40px 36px;
+    border-radius: 24px;
+    background: linear-gradient(135deg, #1a6dff 0%, #004aee 55%, #0035b8 100%);
+    color: #fff;
+    box-shadow: 0 16px 40px rgba(0, 74, 238, 0.28);
+    margin-bottom: 28px;
+  }
+
+  .hero-badge {
+    display: inline-block;
+    padding: 8px 20px;
+    border-radius: 999px;
+    background: rgba(255, 255, 255, 0.18);
+    font-size: 24px;
+    margin-bottom: 24px;
+  }
+
+  .hero-amount {
+    display: flex;
+    align-items: baseline;
+    gap: 12px;
+    margin-bottom: 16px;
+  }
+
+  .amount-num {
+    font-size: 72px;
+    font-weight: 700;
+    line-height: 1;
+  }
+
+  .amount-unit {
+    font-size: 32px;
+    font-weight: 600;
+    opacity: 0.9;
+  }
+
+  .hero-tip {
+    margin: 0;
+    font-size: 26px;
+    line-height: 1.5;
+    opacity: 0.88;
+  }
+
+  .section-card {
+    padding: 32px 28px;
+    border-radius: 20px;
+    margin-bottom: 24px;
+    @include themify() {
+      background: themed("cont_background");
+    }
+    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.04);
+  }
+
+  .section-title {
+    font-size: 32px;
+    font-weight: 600;
+    margin-bottom: 28px;
+    @include themify() {
+      color: themed("text_color");
     }
   }
 
-  .selectDay {
-    position: absolute;
-    left: -70px;
-    background: #f5f5f5;
-    color: #333;
-    box-sizing: border-box;
+  .term-list {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 20px;
+  }
 
-    div {
-      padding: 20px 70px;
+  .term-item {
+    min-width: 120px;
+    padding: 20px 28px;
+    border-radius: 16px;
+    text-align: center;
+    border: 2px solid transparent;
+    transition: all 0.2s;
+    @include themify() {
+      background: themed("tab_background");
+      color: themed("text_color2");
     }
 
-    div:last-child {
+    &.active {
+      border-color: #004aee;
+      background: rgba(0, 74, 238, 0.08);
+      color: #004aee;
+    }
+  }
+
+  .term-days {
+    font-size: 40px;
+    font-weight: 700;
+    margin-right: 4px;
+  }
+
+  .term-unit {
+    font-size: 24px;
+  }
+
+  .info-grid {
+    display: flex;
+    flex-direction: column;
+    gap: 0;
+  }
+
+  .info-row {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 24px 0;
+    border-bottom: 1px solid rgba(134, 142, 155, 0.15);
+
+    &:last-child {
       border-bottom: none;
-      margin-bottom: 0;
+      padding-bottom: 0;
+    }
+
+    &:first-child {
+      padding-top: 0;
     }
   }
 
-  .confirmBtn {
-    border-radius: 8px;
+  .info-label {
+    font-size: 28px;
+    color: #868e9b;
   }
 
-  .grayText {
-    color: #868E9B;
+  .info-value {
+    font-size: 28px;
+    font-weight: 600;
+    text-align: right;
+    max-width: 55%;
+    @include themify() {
+      color: themed("text_color");
+    }
+
+    &.highlight {
+      color: #004aee;
+      font-size: 30px;
+    }
+
+    &.accent {
+      color: #e35461;
+    }
+  }
+
+  .upload-section {
+    margin-bottom: 0;
+  }
+
+  .upload-tip {
+    margin: -12px 0 28px;
+    font-size: 26px;
+    color: #868e9b;
+    line-height: 1.5;
+  }
+
+  .upload-grid {
+    display: grid;
+    grid-template-columns: 1fr 1fr;
+    gap: 24px;
+  }
+
+  .upload-item {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+  }
+
+  .upload-wrap {
+    width: 100%;
+    height: 220px;
+    border-radius: 16px;
+    overflow: hidden;
+    border: 2px dashed rgba(0, 74, 238, 0.25);
+    background: rgba(0, 74, 238, 0.03);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+
+    ::v-deep .van-uploader,
+    ::v-deep .van-uploader__wrapper,
+    ::v-deep .van-uploader__upload,
+    ::v-deep .van-uploader__preview,
+    ::v-deep .van-uploader__preview-image {
+      width: 100% !important;
+      height: 220px !important;
+      margin: 0 !important;
+    }
+
+    ::v-deep .van-uploader__upload-icon {
+      font-size: 48px;
+      color: #004aee;
+    }
+  }
+
+  .upload-label {
+    margin-top: 16px;
+    font-size: 26px;
+    color: #868d9a;
+  }
+
+  .submit-bar {
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    padding: 24px 32px calc(24px + env(safe-area-inset-bottom));
+    @include themify() {
+      background: themed("footer_background");
+    }
+    box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.06);
+    z-index: 20;
+  }
+
+  .submit-btn {
+    width: 100%;
+    height: 96px;
+    border: none;
+    border-radius: 16px;
+    background: linear-gradient(90deg, #1a6dff, #004aee);
+    color: #fff;
+    font-size: 32px;
+    font-weight: 600;
+
+    &:disabled {
+      opacity: 0.6;
+    }
   }
 }
-</style>
\ No newline at end of file
+</style>

--
Gitblit v1.9.3