1
This commit is contained in:
414
src/ui/CJRZQ5E9F/components/RiskAdvice.vue
Normal file
414
src/ui/CJRZQ5E9F/components/RiskAdvice.vue
Normal file
@@ -0,0 +1,414 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user