Files
airz-uniapp/packages/finance/components/MatchProductCard.uvue
T
hujun e5406c23a6 fix: 修复匹配详情提示及公积金可选路径问题
修复匹配详情中“用户自填未经核验”等来源说明,清理未参与项的橙色注意提示,修正贷款统计口径文案;补充公积金完整可选路径提取逻辑,确保明确无额外时长要求的公积金分支可正确识别并通过。
2026-10-19 16:11:59 +08:00

42 lines
5.3 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="match-card" @click="emit('open', item.id)">
<view class="match-head">
<view :class="markClass(item.product.bank)"><image v-if="item.product.logo.length > 0 && !logoFailed" class="institution-logo" :src="item.product.logo" mode="aspectFit" @error="logoFailed = true" /><text v-else class="institution-letter">{{ item.product.bank.length > 0 ? item.product.bank.slice(0, 1) : item.product.name.slice(0, 1) }}</text></view>
<view class="identity"><text v-if="item.product.bank.length > 0" class="institution-name">{{ item.product.bank }}</text><text :class="item.product.bank.length > 0 ? 'product-name' : 'institution-name'">{{ item.product.name }}</text></view>
<view class="match-status"><text v-if="matchPercentage(item.state, item.score).length > 0" :class="item.state == 'eligible' ? 'percentage' : 'percentage reference-percentage'">匹配度 {{ matchPercentage(item.state, item.score) }}</text><text :class="item.state == 'eligible' ? 'state eligible' : (item.state == 'ineligible' ? 'state ineligible' : 'state unknown')">{{ item.stateLabel }}</text></view><text class="arrow">›</text>
</view>
<view class="product-tags"><text v-if="hasProductValue(item.product.rate)" class="product-tag">年化 {{ item.product.rate }}</text><text v-if="hasProductValue(item.product.term)" class="product-tag">{{ item.product.term }}</text><text v-if="hasProductValue(item.product.channel)" class="product-tag">{{ item.product.channel }}</text><text v-if="!hasProductValue(item.product.rate) && !hasProductValue(item.product.term) && !hasProductValue(item.product.channel)" class="product-tag">{{ item.product.objects }}</text></view>
<text v-if="item.availability != 'available'" class="availability">{{ item.availabilityLabel }}</text>
<view v-if="selectable" class="card-actions"><text class="detail-label">查看匹配依据</text><view class="compare-control" @click.stop="emit('select', item.id)"><text :class="selected ? 'selection selected-box' : 'selection'">{{ selected ? '✓' : '+' }}</text><text class="compare-label">{{ selected ? '已选对比' : '加入对比' }}</text></view></view>
</view>
</template>
<script setup lang="uts">
import { MatchView, hasProductValue, matchPercentage } from '@/packages/finance/services/matches.uts'
const props = defineProps({ item: { type: Object as PropType<MatchView>, required: true }, selectable: { type: Boolean, default: false }, selected: { type: Boolean, default: false } })
const emit = defineEmits(['open', 'select'])
const logoFailed = ref(false)
watch((): string => props.item.product.logo, () => { logoFailed.value = false })
const markClass = (bank: string): string => bank.includes('工商') || bank.includes('招商') || bank.includes('中国银行') ? 'institution-mark red' : (bank.includes('农业') || bank.includes('邮储') ? 'institution-mark green' : 'institution-mark blue')
</script>
<style>
.match-card { padding: 28rpx 6rpx 24rpx; border-bottom: 1rpx solid #edf1f6; background-color: #fff; }
.match-head { flex-direction: row; align-items: center; }
.institution-mark { width: 72rpx; height: 72rpx; border-radius: 36rpx; align-items: center; justify-content: center; margin-right: 18rpx; flex-shrink: 0; }
.blue { background-color: #edf4ff; }.red { background-color: #fff0f1; }.green { background-color: #eaf8f2; }
.institution-logo { width: 58rpx; height: 58rpx; }.institution-letter { font-size: 31rpx; color: #1763b9; font-weight: 700; }
.red .institution-letter { color: #bd2e3d; }.green .institution-letter { color: #138a63; }
.identity { flex: 1; min-width: 0; }.institution-name { font-size: 28rpx; line-height: 40rpx; font-weight: 600; color: #24354b; }
.product-name { font-size: 24rpx; line-height: 36rpx; color: #77869a; margin-top: 3rpx; }
.match-status { align-items: flex-end; margin-left: 12rpx; flex-shrink: 0; }.percentage { color: #15946c; font-size: 23rpx; line-height: 36rpx; font-weight: 600; }
.reference-percentage { color: #547aa8; }
.state { font-size: 20rpx; line-height: 30rpx; padding: 2rpx 10rpx; border-radius: 5rpx; margin-top: 3rpx; }
.eligible { color: #19815d; background-color: #eaf8f2; }.ineligible { color: #b56849; background-color: #fff3ed; }.unknown { color: #947125; background-color: #fff8e8; }
.arrow { color: #97a4b5; font-size: 36rpx; margin-left: 14rpx; }
.product-tags { flex-direction: row; flex-wrap: wrap; margin-left: 90rpx; margin-top: 15rpx; }
.product-tag { background-color: #f0f5fc; color: #547aa8; font-size: 20rpx; line-height: 30rpx; padding: 3rpx 9rpx; border-radius: 4rpx; margin-right: 8rpx; margin-bottom: 5rpx; }
.availability { font-size: 21rpx; line-height: 34rpx; color: #9c783a; margin-top: 10rpx; }
.card-actions { flex-direction: row; justify-content: space-between; align-items: center; margin-left: 90rpx; margin-top: 10rpx; }
.detail-label { font-size: 20rpx; color: #8b9aae; }.compare-control { flex-direction: row; align-items: center; padding: 4rpx 0 4rpx 12rpx; }
.selection { width: 28rpx; height: 28rpx; border: 1rpx solid #c3d4e9; border-radius: 6rpx; color: #527ba9; font-size: 22rpx; text-align: center; line-height: 26rpx; }.selected-box { background-color: #0868f7; border-color: #0868f7; color: #fff; }.compare-label { color: #527ba9; font-size: 21rpx; margin-left: 8rpx; }
</style>