2026-09-10 10:57:40 +08:00
|
|
|
<template>
|
2026-09-15 16:16:55 +08:00
|
|
|
<view class="page" :style="pageStyle()">
|
2026-09-18 12:59:43 +08:00
|
|
|
<AppHeader title="产品详情"><text v-if="available" class="share" @click="shareProduct">分享</text></AppHeader>
|
|
|
|
|
<scroll-view scroll-y :style="contentStyle(224, false)">
|
2026-09-10 10:57:40 +08:00
|
|
|
<view class="product-content">
|
2026-09-18 12:59:43 +08:00
|
|
|
<view v-if="loading" class="state"><text class="state-text">正在加载产品…</text></view>
|
|
|
|
|
<view v-else-if="!available" class="state"><text class="state-title">{{ loadFailed ? '产品加载失败' : '暂未找到该产品' }}</text><text class="state-text">请重试或返回方案列表选择其他产品</text><button class="retry-button" @click="loadProduct">重新加载</button></view>
|
|
|
|
|
<view v-else>
|
|
|
|
|
<view class="bank-head"><view class="bank-mark" :style="'background-color:' + product.color"><text class="bank-initial">{{ product.initials }}</text></view><view class="bank-copy"><text class="product-name">{{ product.bank }}</text><text class="product-tags">个人信用融资 · {{ isDemo ? '示例产品' : '产品信息' }}</text></view></view>
|
|
|
|
|
<view class="product-metrics"><view class="metric"><text class="metric-label">最高额度</text><text class="amount">{{ product.amount }}万</text></view><view class="metric"><text class="metric-label">年化利率(起)</text><text class="rate">{{ product.rate.toFixed(2) }}%</text></view><view class="metric last-metric"><text class="metric-label">贷款期限</text><text class="term">{{ product.term }}</text></view></view>
|
|
|
|
|
<view class="detail-section"><text class="section-title">产品优势</text><view class="advantage-grid"><view class="advantage" v-for="item in product.advantages" :key="item"><AppIcon name="check-circle" :size="30" /><text class="advantage-label">{{ item }}</text></view></view></view>
|
|
|
|
|
<view class="detail-section"><text class="section-title">申请条件</text><view class="condition"><text class="condition-label">年龄要求</text><text class="condition-value">{{ product.age }}</text></view><view class="condition"><text class="condition-label">工作要求</text><text class="condition-value">{{ product.work }}</text></view><view class="condition"><text class="condition-label">信用要求</text><text class="condition-value">{{ product.credit }}</text></view></view>
|
|
|
|
|
<view class="detail-section"><text class="section-title">所需材料</text><text class="material">{{ product.materials }}</text></view>
|
|
|
|
|
<text class="product-note">额度、利率及申请条件仅供参考,以机构实际审批为准。{{ isDemo ? '当前可体验申请准备流程,尚未向机构提交资料。' : '' }}</text>
|
|
|
|
|
</view>
|
2026-09-10 10:57:40 +08:00
|
|
|
</view>
|
|
|
|
|
</scroll-view>
|
2026-09-18 12:59:43 +08:00
|
|
|
<view v-if="available" class="apply-bar" :style="bottomStyle(18)"><button class="primary-button apply-button" @click="apply">准备申请</button></view>
|
2026-09-10 10:57:40 +08:00
|
|
|
</view>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="uts">
|
2026-09-15 16:16:55 +08:00
|
|
|
import { usePageLayout } from '@/services/layout.uts'
|
2026-09-20 10:52:10 +08:00
|
|
|
import { FinanceProduct, demoProducts } from '@/packages/finance/services/finance.uts'
|
|
|
|
|
import { fetchProduct, API_BASE_URL } from '@/packages/finance/services/api.uts'
|
2026-09-10 10:57:40 +08:00
|
|
|
import AppHeader from '@/components/AppHeader.uvue'
|
|
|
|
|
import AppIcon from '@/components/AppIcon.uvue'
|
2026-09-18 12:59:43 +08:00
|
|
|
const { bottomStyle, contentStyle, pageStyle } = usePageLayout()
|
|
|
|
|
const product = ref<FinanceProduct>(demoProducts[0])
|
|
|
|
|
const available = ref(false)
|
|
|
|
|
const productId = ref('')
|
|
|
|
|
const loading = ref(true)
|
|
|
|
|
const loadFailed = ref(false)
|
|
|
|
|
const isDemo = API_BASE_URL.length == 0
|
|
|
|
|
const loadProduct = async () => {
|
|
|
|
|
loading.value = true
|
|
|
|
|
loadFailed.value = false
|
|
|
|
|
available.value = false
|
|
|
|
|
try {
|
|
|
|
|
const selected = await fetchProduct(productId.value)
|
|
|
|
|
if (selected != null) { product.value = selected; available.value = true }
|
|
|
|
|
} catch (error) { loadFailed.value = true }
|
|
|
|
|
loading.value = false
|
|
|
|
|
}
|
|
|
|
|
onLoad((options) => {
|
|
|
|
|
productId.value = options?.['id'] ?? ''
|
|
|
|
|
loadProduct()
|
|
|
|
|
})
|
|
|
|
|
const shareProduct = () => {
|
|
|
|
|
const item = product.value
|
|
|
|
|
if (!available.value) return
|
|
|
|
|
uni.setClipboardData({ data: item.bank + '|最高' + item.amount + '万元|年化利率' + item.rate.toFixed(2) + '%起|' + item.term + '。展示信息仅供参考,以机构审批为准。' })
|
|
|
|
|
}
|
|
|
|
|
const apply = () => {
|
|
|
|
|
uni.showModal({
|
|
|
|
|
title: '准备申请资料',
|
|
|
|
|
content: '先完善融资档案,核对申请所需材料。当前尚未开通机构申请,资料不会提交至银行。',
|
|
|
|
|
confirmText: '完善档案',
|
2026-09-20 10:52:10 +08:00
|
|
|
success: (result) => { if (result.confirm) uni.navigateTo({ url: '/packages/finance/archive/archive' }) }
|
2026-09-18 12:59:43 +08:00
|
|
|
})
|
|
|
|
|
}
|
2026-09-10 10:57:40 +08:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style>
|
2026-09-18 12:59:43 +08:00
|
|
|
.share { color: #0868f7; font-size: 25rpx; padding: 16rpx 0 16rpx 16rpx; }
|
|
|
|
|
.product-content { padding: 24rpx 28rpx 60rpx; }
|
|
|
|
|
.bank-head { padding: 26rpx; border-radius: 18rpx; background-color: #fff; border: 1rpx solid #e6edf6; flex-direction: row; align-items: center; }
|
|
|
|
|
.bank-mark { width: 80rpx; height: 80rpx; border-radius: 24rpx; align-items: center; justify-content: center; margin-right: 20rpx; flex-shrink: 0; }
|
|
|
|
|
.bank-initial { color: #fff; font-size: 36rpx; font-weight: 700; }
|
|
|
|
|
.bank-copy { flex: 1; }
|
|
|
|
|
.product-name { font-size: 30rpx; font-weight: 700; color: #20324d; }
|
|
|
|
|
.product-tags { color: #75859b; font-size: 22rpx; margin-top: 10rpx; }
|
|
|
|
|
.product-metrics { margin-top: 20rpx; padding: 30rpx 12rpx; border-radius: 18rpx; background-color: #fff; border: 1rpx solid #e6edf6; flex-direction: row; }
|
|
|
|
|
.metric { flex: 1; align-items: center; border-right: 1rpx solid #edf1f6; }
|
|
|
|
|
.last-metric { border-right: 0; }
|
|
|
|
|
.metric-label { color: #75859b; font-size: 21rpx; }
|
|
|
|
|
.amount, .rate, .term { margin-top: 14rpx; font-size: 36rpx; line-height: 46rpx; font-weight: 800; color: #20324d; }
|
2026-09-15 16:16:55 +08:00
|
|
|
.rate { color: #0868f7; }
|
2026-09-18 12:59:43 +08:00
|
|
|
.term { font-size: 27rpx; }
|
|
|
|
|
.detail-section { margin-top: 20rpx; padding: 26rpx; background-color: #fff; border-radius: 18rpx; border: 1rpx solid #e6edf6; }
|
|
|
|
|
.advantage-grid { margin-top: 24rpx; flex-direction: row; flex-wrap: wrap; }
|
|
|
|
|
.advantage { width: 50%; flex-direction: row; align-items: center; margin-bottom: 16rpx; }
|
|
|
|
|
.advantage-label { margin-left: 12rpx; font-size: 25rpx; color: #435168; }
|
|
|
|
|
.condition { min-height: 78rpx; padding: 14rpx 0; flex-direction: row; justify-content: space-between; align-items: center; border-bottom: 1rpx solid #edf1f6; }
|
|
|
|
|
.condition-label { color: #748399; font-size: 24rpx; flex-shrink: 0; margin-right: 20rpx; }
|
|
|
|
|
.condition-value { flex: 1; text-align: right; color: #273b54; font-size: 24rpx; line-height: 36rpx; }
|
|
|
|
|
.material { margin-top: 18rpx; font-size: 24rpx; line-height: 38rpx; color: #53667f; }
|
|
|
|
|
.product-note { margin: 22rpx 6rpx 0; color: #7a899e; font-size: 21rpx; line-height: 34rpx; }
|
2026-09-15 16:16:55 +08:00
|
|
|
.apply-bar { position: fixed; left: 0; right: 0; bottom: 0; padding: 18rpx 28rpx; background-color: #fff; border-top: 1rpx solid #e7edf6; }
|
|
|
|
|
.apply-button { margin: 0; }
|
2026-09-18 12:59:43 +08:00
|
|
|
.state { padding: 80rpx 24rpx; align-items: center; }
|
|
|
|
|
.state-title { font-size: 30rpx; color: #20324d; font-weight: 600; margin-bottom: 14rpx; }
|
|
|
|
|
.state-text { font-size: 25rpx; line-height: 40rpx; text-align: center; color: #75859b; }
|
|
|
|
|
.retry-button { margin-top: 24rpx; color: #0868f7; background-color: #e8f2ff; font-size: 25rpx; }
|
2026-09-10 10:57:40 +08:00
|
|
|
</style>
|