fix: 修复匹配详情提示及公积金可选路径问题
修复匹配详情中“用户自填未经核验”等来源说明,清理未参与项的橙色注意提示,修正贷款统计口径文案;补充公积金完整可选路径提取逻辑,确保明确无额外时长要求的公积金分支可正确识别并通过。
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<view class="province-row" @click="open"><text class="province-label">所在省份</text><text :class="isSelected ? 'province-value' : 'province-value province-placeholder'">{{ isSelected ? modelValue : '请选择省份' }}</text><AppIcon name="chevron-right" :size="28" /></view>
|
||||
<view v-if="opened" class="province-mask" @click="cancel">
|
||||
<view class="province-sheet" @click.stop="noop">
|
||||
<view class="province-toolbar"><text class="province-title">选择所在省份</text><text class="province-cancel" @click="cancel">取消</text></view>
|
||||
<scroll-view scroll-y class="province-list" :scroll-top="selectedTop">
|
||||
<view v-for="item in provinceOptions" :key="item.code" :id="'province-' + item.code" :class="item.name == modelValue ? 'province-option province-active' : 'province-option'" @click="choose(item.name)"><text class="province-option-name">{{ item.name }}</text><text v-if="item.name == modelValue" class="province-check">✓</text></view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="uts">
|
||||
import AppIcon from '@/components/AppIcon.uvue'
|
||||
import { provinceOptions, provinceCodeForName } from '@/services/cities.uts'
|
||||
const props = defineProps({ modelValue: { type: String, default: '' } })
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const opened = ref(false)
|
||||
const selectedTop = ref(0)
|
||||
const isSelected = computed((): boolean => provinceCodeForName(props.modelValue) != null)
|
||||
const noop = () => {}
|
||||
const open = () => {
|
||||
uni.hideKeyboard(); selectedTop.value = 0; opened.value = true
|
||||
const index = provinceOptions.findIndex((item): boolean => item.name == props.modelValue)
|
||||
nextTick(() => { selectedTop.value = Math.max(0, index - 2) * 94 * uni.getWindowInfo().windowWidth / 750 })
|
||||
}
|
||||
const cancel = () => { opened.value = false }
|
||||
const choose = (name: string) => { emit('update:modelValue', name); opened.value = false }
|
||||
</script>
|
||||
<style>
|
||||
.province-row { min-height: 106rpx; flex-direction: row; align-items: center; border-bottom: 1rpx solid #edf1f6; }
|
||||
.province-label { font-size: 28rpx; color: #29374e; margin-right: 16rpx; flex-shrink: 0; }
|
||||
.province-value { flex: 1; min-width: 0; margin-right: 12rpx; text-align: right; color: #22324a; font-size: 27rpx; line-height: 38rpx; }
|
||||
.province-placeholder { color: #8995a7; }
|
||||
.province-mask { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1000; background-color: rgba(20, 32, 52, 0.4); justify-content: flex-end; }
|
||||
.province-sheet { background-color: #ffffff; border-top-left-radius: 24rpx; border-top-right-radius: 24rpx; padding-bottom: 48rpx; }
|
||||
.province-toolbar { height: 112rpx; flex-direction: row; align-items: center; justify-content: space-between; padding-left: 32rpx; padding-right: 32rpx; }
|
||||
.province-title { font-size: 30rpx; color: #22324a; font-weight: 600; }
|
||||
.province-cancel { font-size: 28rpx; color: #6e7e95; padding: 16rpx; }
|
||||
.province-list { height: 650rpx; }
|
||||
.province-option { height: 94rpx; padding-left: 40rpx; padding-right: 40rpx; flex-direction: row; align-items: center; justify-content: space-between; }
|
||||
.province-option-name { color: #22324a; font-size: 28rpx; }
|
||||
.province-active { background-color: #eef4ff; }
|
||||
.province-check { color: #2468ec; font-size: 30rpx; }
|
||||
</style>
|
||||
@@ -0,0 +1,41 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user