Files
airz-uniapp/pages/matches/matches.uvue
T
hujun 626cef9d38 feat: 完成全流程融资助手应用开发
- 新增文章、课程详情页面,完善融资课堂模块
- 新增登录/注册、评估填报、结果匹配全流程业务
- 新增会话管理、错误重试与状态加载逻辑
- 重构首页路由逻辑,适配已登录用户跳转
- 完善个人中心登出与数据持久化功能
2026-09-11 20:23:10 +08:00

48 lines
4.8 KiB
Plaintext

<template>
<view class="page">
<AppHeader title="为您匹配到 3 个方案" />
<view class="filter-bar"><view :class="filter == 'all' ? 'filter active' : 'filter'" @click="filter='all'"><text>综合排序</text></view><view :class="filter == 'amount' ? 'filter active' : 'filter'" @click="filter='amount'"><text>额度高</text></view><view :class="filter == 'rate' ? 'filter active' : 'filter'" @click="filter='rate'"><text>利率低</text></view></view>
<scroll-view scroll-y class="match-scroll">
<view class="match-content">
<view v-if="loading" class="state-panel"><text>正在为您匹配方案...</text></view>
<view v-else-if="errorMessage.length > 0" class="state-panel error-panel"><text>{{ errorMessage }}</text><button class="retry-button" @click="loadMatches">重新加载</button></view>
<view class="match-card" v-for="item in matches" :key="item.rank">
<view :class="'rank rank-' + item.rank"><text>{{ item.rank }}</text></view>
<view class="bank-logo"><AppIcon name="building" :size="40" /></view>
<view class="match-main"><text class="bank-name">{{ item.bank }}</text><text class="match-tag">个人信用贷 · 资料简</text><view class="metrics"><view><text class="metric-value">{{ item.amount }}</text><text class="metric-label">最高额度</text></view><view><text class="metric-value rate-value">{{ item.rate }}</text><text class="metric-label">年利率</text></view><view><text class="metric-value">{{ item.term }}</text><text class="metric-label">贷款期限</text></view></view></view>
<button class="detail-button" @click="openProduct(item.rank)">查看详情</button>
</view>
<text class="list-tip">匹配结果基于您的评估信息,实际额度以机构审批为准</text>
</view>
</scroll-view>
<BottomNav active="" />
</view>
</template>
<script setup lang="uts">
import AppHeader from '@/components/AppHeader.uvue'
import BottomNav from '@/components/BottomNav.uvue'
import { fetchMatches } from '@/services/api.uts'
import AppIcon from '@/components/AppIcon.uvue'
const filter = ref('all')
const matches = ref<UTSJSONObject[]>([])
const loading = ref(true)
const errorMessage = ref('')
const loadMatches = async () => {
loading.value = true
errorMessage.value = ''
try { matches.value = await fetchMatches() } catch (error) { errorMessage.value = '匹配方案加载失败,请重试' }
loading.value = false
}
onMounted(() => { loadMatches() })
const openProduct = (rank: number) => { uni.navigateTo({ url: '/pages/product/product?id=' + rank }) }
</script>
<style>
.filter-bar { height: 92rpx; background-color: #fff; flex-direction: row; align-items: center; padding: 0 30rpx; border-bottom: 1rpx solid #e9eef6; }.filter { flex: 1; height: 92rpx; align-items: center; justify-content: center; color: #758298; font-size: 24rpx; }.filter.active { color: #0868f7; font-weight: 700; border-bottom: 4rpx solid #0868f7; }
.match-scroll { height: calc(100vh - var(--status-bar-height) - 318rpx); }.match-content { padding: 24rpx 28rpx 150rpx; }.match-card { min-height: 310rpx; border-radius: 18rpx; margin-bottom: 22rpx; background-color: #fff; border: 1rpx solid #e4ebf5; padding: 26rpx 22rpx 22rpx; position: relative; flex-direction: row; box-shadow: 0 8rpx 24rpx rgba(24, 54, 95, .05); }.rank { position: absolute; left: -7rpx; top: 20rpx; width: 48rpx; height: 48rpx; color: white; border-radius: 0 24rpx 24rpx 0; align-items: center; justify-content: center; font-weight: 800; }.rank-1 { background-color: #ff8a13; }.rank-2 { background-color: #16b48a; }.rank-3 { background-color: #ee3333; }
.bank-logo { width: 78rpx; height: 78rpx; border-radius: 50%; background-color: #e41e2b; color: white; align-items: center; justify-content: center; font-size: 30rpx; font-weight: 800; margin-left: 22rpx; margin-right: 18rpx; }.match-main { flex: 1; }.bank-name { font-size: 28rpx; font-weight: 800; }.match-tag { color: #8794a7; font-size: 20rpx; margin-top: 8rpx; }.metrics { flex-direction: row; justify-content: space-between; margin-top: 30rpx; }.metrics view { flex: 1; }.metric-value { font-size: 26rpx; font-weight: 800; color: #1c2a41; }.rate-value { color: #0868f7; }.metric-label { margin-top: 7rpx; font-size: 18rpx; color: #95a0b1; }
.detail-button { position: absolute; right: 22rpx; bottom: 18rpx; width: 160rpx; height: 62rpx; line-height: 62rpx; border-radius: 12rpx; margin: 0; padding: 0; background-color: #0868f7; color: white; font-size: 22rpx; font-weight: 700; }.list-tip { text-align: center; color: #9ca8b8; font-size: 20rpx; line-height: 34rpx; margin: 12rpx 30rpx; }
.state-panel { min-height: 260rpx; align-items: center; justify-content: center; color: #8793a6; font-size: 24rpx; }.error-panel { color: #e05a5a; }.retry-button { margin-top: 20rpx; height: 64rpx; line-height: 64rpx; border-radius: 12rpx; color: #0868f7; background-color: #e8f2ff; font-size: 22rpx; }
</style>