415 lines
14 KiB
Vue
415 lines
14 KiB
Vue
<template>
|
||
<div class="rounded-lg border border-[#99999933] mb-4">
|
||
<!-- 标题栏 -->
|
||
<div class="flex items-center p-4">
|
||
<div class="w-8 h-8 flex items-center justify-center mr-2">
|
||
<img src="@/assets/images/report/zyjy.png" alt="专业建议" class="w-8 h-8 object-contain" />
|
||
</div>
|
||
<span class="font-bold text-gray-800">专业建议</span>
|
||
</div>
|
||
|
||
<!-- 风险评估结论 -->
|
||
<div class="mb-6 px-4">
|
||
<div class="rounded-xl p-4 relative border" :class="overallRiskLevel.bgClass">
|
||
<!-- 风险分标签 -->
|
||
<div
|
||
class="absolute top-0 right-0 px-3 py-1 rounded-bl-lg rounded-tr-lg text-sm font-bold text-white whitespace-nowrap"
|
||
:class="getRiskBadgeClass()">
|
||
风险分:{{ overallRiskScore }}
|
||
</div>
|
||
|
||
<div class="flex items-center gap-4 mb-3">
|
||
<div class="w-10 h-10 flex-shrink-0">
|
||
<img :src="getRiskIcon()" :alt="overallRiskLevel.title" class="w-10 h-10 object-contain" />
|
||
</div>
|
||
<div class="flex-1">
|
||
<h3 class="text-base font-bold text-[#333333]">{{ overallRiskLevel.title }}</h3>
|
||
<p class="text-sm text-[#999999]">{{ overallRiskLevel.subtitle }}</p>
|
||
</div>
|
||
</div>
|
||
<div class="text-sm text-[#333333] leading-relaxed">
|
||
{{ overallRiskLevel.description }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 关键建议 -->
|
||
<div class="mb-6">
|
||
<LTitle title="关键建议" class="mb-2" />
|
||
|
||
<div class="space-y-3 px-4">
|
||
<div class="rounded-xl p-4 relative" v-for="recommendation in keyRecommendations" :key="recommendation.id"
|
||
:class="getRecommendationCardClass(recommendation.priority)">
|
||
<!-- 优先级标签 -->
|
||
<div class="absolute top-0 right-0 px-2 py-1 rounded-bl-lg rounded-tr-lg text-xs font-bold text-white"
|
||
:class="getRecommendationBadgeClass(recommendation.priority)">
|
||
{{ recommendation.priorityText }}
|
||
</div>
|
||
|
||
<div class="flex items-center gap-3">
|
||
<div class="w-10 h-10 flex-shrink-0">
|
||
<img :src="getRecommendationIcon(recommendation.priority)" :alt="recommendation.title"
|
||
class="w-10 h-10 object-contain" />
|
||
</div>
|
||
<div class="flex-1 min-w-0">
|
||
<h4 class="text-base font-bold text-[#333333] mb-2">{{ recommendation.title }}</h4>
|
||
<p class="text-sm text-[#999999] mb-3 leading-relaxed">{{ recommendation.description }}</p>
|
||
<div class="flex flex-wrap gap-2" v-if="recommendation.actions.length > 0">
|
||
<span class="inline-flex items-center px-3 py-1 rounded-xl text-sm"
|
||
:class="getRecommendationActionClass(recommendation.priority)"
|
||
v-for="action in recommendation.actions.slice(0, 3)" :key="action">
|
||
{{ action }}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 温馨提示 -->
|
||
<!-- <div class="px-4 pb-4">
|
||
<LRemark
|
||
content="专业建议基于综合风险评估结果,为不同风险等级的申请人提供针对性的审核廊议和风险管控措施。建议内容包括关键建议、风险管控措施、注意事项和后续跟进等方面。系统会根据当前风险等级动态调整建议内容,但最终决策仍需结合具体业务情况和风险政策进行综合判断。建议定期复评风险状况和调整风险管控策略。" />
|
||
</div> -->
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import LTitle from '@/components/LTitle.vue'
|
||
import LRemark from '@/components/LRemark.vue'
|
||
|
||
export default {
|
||
name: 'RiskAdvice',
|
||
components: {
|
||
LTitle,
|
||
LRemark
|
||
},
|
||
props: {
|
||
data: {
|
||
type: Object,
|
||
default: () => ({})
|
||
}
|
||
},
|
||
computed: {
|
||
// 综合风险评估
|
||
overallRiskScore() {
|
||
const creditScore = parseFloat(this.data.xyp_cpl0081) || 0
|
||
const amountIndex = parseFloat(this.data.xyp_cpl0082) || 0
|
||
const countIndex = parseFloat(this.data.xyp_cpl0083) || 0
|
||
|
||
// 风险分数 (0-100, 分数越高风险越低)
|
||
const avgRisk = (creditScore + amountIndex + countIndex) / 3
|
||
return Math.round((1 - avgRisk) * 100)
|
||
},
|
||
|
||
overallRiskLevel() {
|
||
const score = this.overallRiskScore
|
||
const hasCurrentOverdue = this.data.xyp_cpl0044 === '1'
|
||
const hasRecentOverdue = this.data.xyp_cpl0028 === '1' || this.data.xyp_cpl0029 === '1'
|
||
|
||
if (hasCurrentOverdue || score < 30) {
|
||
return {
|
||
title: '高风险用户',
|
||
subtitle: '需要立即关注',
|
||
description: '当前信用状况较差,建议立即处理逾期问题并暂停新申请。',
|
||
bgClass: 'bg-red-50 border-red-200',
|
||
iconBg: 'bg-red-500',
|
||
iconComponent: 'ExclamationTriangleIcon'
|
||
}
|
||
} else if (hasRecentOverdue || score < 60) {
|
||
return {
|
||
title: '中风险用户',
|
||
subtitle: '需要改善',
|
||
description: '信用状况一般,建议优化还款表现并控制申请频率。',
|
||
bgClass: 'bg-yellow-50 border-yellow-200',
|
||
iconBg: 'bg-yellow-500',
|
||
iconComponent: 'ExclamationCircleIcon'
|
||
}
|
||
} else {
|
||
return {
|
||
title: '低风险用户',
|
||
subtitle: '状况良好',
|
||
description: '信用状况良好,建议继续保持良好的还款习惯。',
|
||
bgClass: 'bg-green-50 border-green-200',
|
||
iconBg: 'bg-green-500',
|
||
iconComponent: 'CheckCircleIcon'
|
||
}
|
||
}
|
||
},
|
||
|
||
// 关键建议
|
||
keyRecommendations() {
|
||
const recommendations = []
|
||
|
||
// 当前逾期处理
|
||
if (this.data.xyp_cpl0044 === '1') {
|
||
recommendations.push({
|
||
id: 'handle_overdue',
|
||
title: '立即处理逾期',
|
||
description: '尽快联系机构协商还款,避免影响征信。',
|
||
priority: 'urgent',
|
||
priorityText: '紧急',
|
||
iconComponent: 'ExclamationTriangleIcon',
|
||
iconBg: 'bg-red-500',
|
||
borderClass: 'border-l-red-500',
|
||
badgeClass: 'bg-red-100 text-red-800',
|
||
actions: [
|
||
'联系机构协商',
|
||
'优先还小额',
|
||
'制定还款计划'
|
||
]
|
||
})
|
||
}
|
||
|
||
// 高频申请警告
|
||
const recent1Day = this.parseIntervalValue(this.data.xyp_cpl0070)
|
||
const recent7Day = this.parseIntervalValue(this.data.xyp_cpl0009)
|
||
if (recent1Day > 0 || recent7Day > 5) {
|
||
recommendations.push({
|
||
id: 'reduce_applications',
|
||
title: '控制申请频率',
|
||
description: '近期申请过频,建议暂停新申请3-6个月。',
|
||
priority: 'high',
|
||
priorityText: '重要',
|
||
iconComponent: 'PauseCircleIcon',
|
||
iconBg: 'bg-orange-500',
|
||
borderClass: 'border-l-orange-500',
|
||
badgeClass: 'bg-orange-100 text-orange-800',
|
||
actions: [
|
||
'暂停新申请',
|
||
'整理现有贷款',
|
||
'制定资金规划'
|
||
]
|
||
})
|
||
}
|
||
|
||
// 还款表现改善
|
||
const successRate = parseFloat(this.data.xyp_cpl0080) || 0
|
||
const recent5SuccessRate = parseFloat(this.data.xyp_cpl0074) || 0
|
||
const recent20SuccessRate = parseFloat(this.data.xyp_t0400002) || 0
|
||
|
||
if (successRate < 0.8 || recent5SuccessRate < 0.8 || recent20SuccessRate < 0.8) {
|
||
recommendations.push({
|
||
id: 'improve_repayment',
|
||
title: '提升还款表现',
|
||
description: `还款成功率偏低,建议设置自动还款。`,
|
||
priority: 'high',
|
||
priorityText: '重要',
|
||
iconComponent: 'CalendarIcon',
|
||
iconBg: 'bg-blue-500',
|
||
borderClass: 'border-l-blue-500',
|
||
badgeClass: 'bg-blue-100 text-blue-800',
|
||
actions: [
|
||
'设置自动还款',
|
||
'确保账户余额',
|
||
'按时还款'
|
||
]
|
||
})
|
||
}
|
||
|
||
// 机构数量管理
|
||
const totalInstitutions = this.parseIntervalValue(this.data.xyp_cpl0001)
|
||
if (totalInstitutions > 10) {
|
||
recommendations.push({
|
||
id: 'manage_institutions',
|
||
title: '优化机构数量',
|
||
description: '机构数量较多,建议优先结清小额贷款。',
|
||
priority: 'medium',
|
||
priorityText: '建议',
|
||
iconComponent: 'AdjustmentsIcon',
|
||
iconBg: 'bg-purple-500',
|
||
borderClass: 'border-l-purple-500',
|
||
badgeClass: 'bg-purple-100 text-purple-800',
|
||
actions: [
|
||
'结清小额贷款',
|
||
'合并同类贷款',
|
||
'控制新增机构'
|
||
]
|
||
})
|
||
}
|
||
|
||
// 交易失败后恢复分析
|
||
const consumerFailureRecoveryDays = this.parseIntervalValue(this.data.xyp_cpl0054)
|
||
const smallLoanFailureRecoveryDays = this.parseIntervalValue(this.data.xyp_cpl0055)
|
||
const overallFailureRecoveryDays = this.parseIntervalValue(this.data.xyp_cpl0056)
|
||
|
||
if (consumerFailureRecoveryDays > 30 || smallLoanFailureRecoveryDays > 30 || overallFailureRecoveryDays > 30) {
|
||
recommendations.push({
|
||
id: 'improve_recovery_time',
|
||
title: '快速恢复能力',
|
||
description: '失败后恢复较慢,建议建立应急资金。',
|
||
priority: 'medium',
|
||
priorityText: '建议',
|
||
iconComponent: 'ClockIcon',
|
||
iconBg: 'bg-indigo-500',
|
||
borderClass: 'border-l-indigo-500',
|
||
badgeClass: 'bg-indigo-100 text-indigo-800',
|
||
actions: [
|
||
'建立应急资金',
|
||
'优化资金流',
|
||
'快速处理失败'
|
||
]
|
||
})
|
||
}
|
||
|
||
// 信用修复
|
||
const settledInstitutions = this.parseIntervalValue(this.data.xyp_cpl0002)
|
||
if (settledInstitutions > 0) {
|
||
recommendations.push({
|
||
id: 'credit_repair',
|
||
title: '继续信用修复',
|
||
description: '已有良好结清记录,建议继续保持。',
|
||
priority: 'medium',
|
||
priorityText: '建议',
|
||
iconComponent: 'TrendingUpIcon',
|
||
iconBg: 'bg-green-500',
|
||
borderClass: 'border-l-green-500',
|
||
badgeClass: 'bg-green-100 text-green-800',
|
||
actions: [
|
||
'保持还款记录',
|
||
'结清剩余贷款',
|
||
'稳定收入来源'
|
||
]
|
||
})
|
||
}
|
||
|
||
return recommendations
|
||
},
|
||
|
||
// 改善步骤
|
||
improvementSteps() {
|
||
const steps = []
|
||
|
||
if (this.data.xyp_cpl0044 === '1') {
|
||
steps.push({
|
||
id: 'immediate_action',
|
||
title: '立即行动期',
|
||
description: '处理逾期问题,停止新申请',
|
||
duration: '1-2周',
|
||
impact: '高',
|
||
badgeClass: 'bg-red-100 text-red-800'
|
||
})
|
||
}
|
||
|
||
steps.push({
|
||
id: 'stabilization',
|
||
title: '稳定期',
|
||
description: '建立稳定还款计划,按时还款',
|
||
duration: '3-6个月',
|
||
impact: '中',
|
||
badgeClass: 'bg-yellow-100 text-yellow-800'
|
||
})
|
||
|
||
steps.push({
|
||
id: 'optimization',
|
||
title: '优化期',
|
||
description: '减少机构数量,优化债务结构',
|
||
duration: '6-12个月',
|
||
impact: '中',
|
||
badgeClass: 'bg-yellow-100 text-yellow-800'
|
||
})
|
||
|
||
steps.push({
|
||
id: 'recovery',
|
||
title: '恢复期',
|
||
description: '建立良好信用记录,恢复信用状况',
|
||
duration: '12-24个月',
|
||
impact: '高',
|
||
badgeClass: 'bg-green-100 text-green-800'
|
||
})
|
||
|
||
return steps
|
||
}
|
||
},
|
||
|
||
methods: {
|
||
parseIntervalValue(value) {
|
||
if (!value || value === '' || value === '-1') return 0
|
||
const num = parseInt(value)
|
||
if (isNaN(num)) return 0
|
||
|
||
// 根据区间映射返回大致范围的中值
|
||
switch (num) {
|
||
case 1: return 1
|
||
case 2: return 3
|
||
case 3: return 7
|
||
case 4: return 15
|
||
case 5: return 25
|
||
default: return num
|
||
}
|
||
},
|
||
|
||
getRiskIcon() {
|
||
// 根据风险等级返回对应的图标
|
||
if (this.overallRiskLevel.iconComponent === 'ExclamationTriangleIcon') {
|
||
return new URL('@/assets/images/report/gfx.png', import.meta.url).href
|
||
} else if (this.overallRiskLevel.iconComponent === 'ExclamationCircleIcon') {
|
||
return new URL('@/assets/images/report/zfx.png', import.meta.url).href
|
||
} else {
|
||
return new URL('@/assets/images/report/zq.png', import.meta.url).href
|
||
}
|
||
},
|
||
|
||
getRiskBadgeClass() {
|
||
// 根据风险等级返回徽章样式
|
||
if (this.overallRiskLevel.iconComponent === 'ExclamationTriangleIcon') {
|
||
return 'bg-[#D44643]'
|
||
} else if (this.overallRiskLevel.iconComponent === 'ExclamationCircleIcon') {
|
||
return 'bg-[#F5A623]'
|
||
} else {
|
||
return 'bg-[#5EBC62]'
|
||
}
|
||
},
|
||
|
||
getRecommendationCardClass(priority) {
|
||
// 根据优先级返回卡片样式
|
||
if (priority === 'urgent') {
|
||
return 'bg-[#FFF0F0] border border-[#F0CACA]'
|
||
} else if (priority === 'high') {
|
||
return 'bg-[#ECF2FD] border border-[#CADAF9]'
|
||
} else {
|
||
return 'bg-[#F0FFF0] border border-green-200'
|
||
}
|
||
},
|
||
|
||
getRecommendationIcon(priority) {
|
||
// 根据优先级返回图标
|
||
if (priority === 'urgent') {
|
||
return new URL('@/assets/images/report/gfx.png', import.meta.url).href
|
||
} else if (priority === 'high') {
|
||
return new URL('@/assets/images/report/wxts_icon.png', import.meta.url).href
|
||
} else {
|
||
return new URL('@/assets/images/report/zq.png', import.meta.url).href
|
||
}
|
||
},
|
||
|
||
getRecommendationBadgeClass(priority) {
|
||
// 根据优先级返回徽章样式
|
||
if (priority === 'urgent') {
|
||
return 'bg-[#D44643]'
|
||
} else if (priority === 'high') {
|
||
return 'bg-[#5079EA]'
|
||
} else {
|
||
return 'bg-[#5EBC62]'
|
||
}
|
||
},
|
||
|
||
getRecommendationActionClass(priority) {
|
||
// 根据优先级返回操作按钮样式
|
||
if (priority === 'urgent') {
|
||
return 'bg-[#F0CACA] text-[#D44643]'
|
||
} else if (priority === 'high') {
|
||
return 'bg-[#DBE6FC] text-[#2B79EE]'
|
||
} else {
|
||
return 'bg-green-200 text-[#5EBC62]'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
/* 组件样式已使用 Tailwind CSS */
|
||
</style>
|