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