This commit is contained in:
2026-02-11 15:02:56 +08:00
parent 51ad490293
commit 9bb7c4ddae
5 changed files with 535 additions and 4 deletions

149
src/ui/JRZQ8B3C/README.md Normal file
View File

@@ -0,0 +1,149 @@
# 个人消费能力等级组件 (JRZQ8B3C)
## 组件概述
基于个人收入指数评分进行消费能力等级评估,为企业提供专业的消费能力分析和风险评估服务。
## 组件结构
```
JRZQ8B3C/
├── index.vue # 主组件
└── README.md # 说明文档
```
## 使用方法
### 基本用法
```vue
<template>
<div>
<JRZQ8B3C :data="consumptionData" />
</div>
</template>
<script setup>
import JRZQ8B3C from '@/ui/JRZQ8B3C/index.vue'
// 个人消费能力等级数据示例
const consumptionData = {
personincome_index_2.0: "200" // 个人收入指数评分(字符串类型)
}
</script>
```
## 数据字段说明
| 字段名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| personincome_index_2.0 | String | 是 | 个人收入指数评分 | "200" |
## 评分分档说明
| 分值 | 收入区间(元/月) | 消费能力等级 | 风险等级 |
|------|----------------|------------|----------|
| -1 | **未命中** | 无法获取收入信息 | 高风险 |
| 100 | (1000, 2000] | 第1档 | 高风险 |
| 200 | (2000, 4000] | 第2档 | 高风险 |
| 300 | (4000, 6000] | 第3档 | 高风险 |
| 400 | (6000, 8000] | 第4档 | 中等风险 |
| 500 | (8000, 10000] | 第5档 | 中等风险 |
| 600 | (10000, 12000] | 第6档 | 中等风险 |
| 700 | (12000, 15000] | 第7档 | 低风险 |
| 800 | (15000, 20000] | 第8档 | 低风险 |
| 900 | (20000, 25000] | 第9档 | 低风险 |
| 1000 | (25000, +∞) | 第10档 | 低风险 |
## 特殊值说明
- **-1**: 表示未命中(无法获取收入信息)
- **评分范围**: 100-1000分共10个等级
- **等级意义**: 等级越高,对应的消费能力越强
- **区间定义**: 收入区间为左开右闭区间1000 < 收入 2000
## 组件特性
### 1. 专业的视觉展示
- **评分展示**大数字显示个人收入指数评分
- **进度条可视化**直观展示评分在100-1000分范围内的位置
- **颜色编码**根据评分等级使用不同颜色=红色,中=黄色,高=绿色)
- **响应式设计**完美适配各种屏幕尺寸
### 2. 全面的数据分析
- **收入区间显示**清晰展示对应的月收入范围
- **等级描述**显示当前评分对应的消费能力等级
- **市场对比分析**与市场平均水平对比
- **消费能力评估**基于收入指数的消费能力分析
### 3. 智能风险评估
- **动态评分**根据收入指数自动计算风险分数30-100分
- **风险等级标签**直观显示当前风险等级
- **个性化建议**针对不同等级的专业建议
## 视觉设计亮点
### 1. 色彩系统
- **低风险700-1000分**绿色系表示消费能力强
- **中等风险400-600分**黄色系表示消费能力中等
- **高风险100-300分/-1**红色系表示消费能力有限
### 2. 交互体验
- 平滑的动画过渡
- 直观的视觉反馈
- 清晰的信息层次
### 3. 信息架构
- 层次分明的信息展示
- 重点突出的核心数据
- 完整的补充说明
## 数据说明
### 评估依据
- 基于个人收入指数评分
- 使用10档分级评分体系
- 数据准确可靠
### 使用限制
- 收入范围为税前月收入
- 存在地区差异仅供参考
- 建议结合其他收入证明材料
### 评分计算
- 风险评分范围30-100分
- 100分对应30分风险评分
- 1000分对应100分风险评分最安全
- -1未命中对应30分风险评分
## 业务价值
### 1. 风险控制
- 精确的消费能力评估降低信贷风险
- 多维度风险分析提升决策质量
- 智能化评分系统提高效率
### 2. 客户分层
- 基于消费能力的客户分级管理
- 个性化服务策略制定
- 精准的市场定位分析
### 3. 合规要求
- 符合金融监管要求
- 数据来源权威可靠
- 评估过程透明公开
## 注意事项
1. 确保传入正确的 `personincome_index_2.0`
2. 组件会自动处理 -1 特殊值未命中
3. 建议在网络良好的环境下使用
4. 定期更新评估标准以保持准确性
## 更新日志
- v1.0.0 - 初始版本支持基础消费能力等级评估功能
- 专业的视觉展示效果
- 完整的评分分档系统
- 专业的风险分析功能

377
src/ui/JRZQ8B3C/index.vue Normal file
View File

@@ -0,0 +1,377 @@
<template>
<div class="card">
<div class="rounded-lg border border-gray-200 pb-2 mb-4">
<!-- 标题区域 -->
<div class="flex items-center mb-4 p-4">
<div class="w-8 h-8 flex items-center justify-center mr-2">
<img src="@/assets/images/report/srpg.png" alt="个人消费能力等级" class="w-8 h-8 object-contain" />
</div>
<span class="font-bold text-gray-800">个人消费能力等级</span>
</div>
<div class="px-4 pb-4">
<!-- 月消费能力 -->
<div class="mb-6 text-center">
<div class="text-sm text-gray-600 mb-2">月消费能力</div>
<div class="text-3xl font-bold mb-3 text-[#333333]">
<span class="amount-number">{{ getConsumptionAmount(score) }}</span>
<span class="amount-unit">/</span>
</div>
<div class="level-bar" :style="getLevelBarBgStyle(score)">
<div class="level-fill" :style="getLevelBarStyle(score)"></div>
</div>
<div class="text-sm text-gray-600 mt-2">{{ getConsumptionDescription(score) }}</div>
</div>
<!-- 评估结果 -->
<div class="assessment-card">
<div class="flex items-center">
<div class="flex-1">
<div class="flex items-center justify-between mb-2">
<h4 class="font-semibold text-gray-800">评估结果</h4>
</div>
<p class="text-gray-400 text-sm">
{{ getAssessmentDescription(score) }}
</p>
</div>
</div>
</div>
<!-- 市场对比 -->
<div class="assessment-card">
<div class="flex items-center mb-8">
<div class="flex-1">
<div class="flex items-center justify-between mb-2">
<h4 class="font-semibold text-gray-800">市场对比</h4>
</div>
<p class="text-gray-400 text-sm">
{{ getMarketComparison(score) }}
</p>
</div>
</div>
<div class="comparison-indicator mt-4">
<div class="indicator-bar">
<div class="indicator-fill" :style="getIndicatorStyle(score)"></div>
<div class="indicator-marker" :style="getMarkerPosition(score)">
<img src="@/assets/images/report/srbq.png" alt="市场对比" class="marker-image" />
<div class="marker-dot"></div>
</div>
</div>
<div class="indicator-labels">
<span>低消费</span>
<span>高消费</span>
</div>
</div>
</div>
<!-- 消费能力 -->
<div class="assessment-card">
<div class="flex items-center">
<div class="flex-1">
<div class="mb-2">
<h4 class="font-semibold text-gray-800">消费能力</h4>
</div>
<p class="text-gray-400 text-sm">
{{ getConsumptionCapacity(score) }}
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue'
import { useRiskNotifier } from '@/composables/useRiskNotifier';
const props = defineProps({
data: {
type: Object,
required: true,
default: () => ({})
},
apiId: {
type: String,
default: '',
},
index: {
type: Number,
default: 0,
},
notifyRiskStatus: {
type: Function,
default: () => { },
},
})
// 确保data是响应式的
const data = computed(() => props.data || {})
// 获取评分值(字符串转数字,处理-1特殊值
const score = computed(() => {
const value = data.value['personincome_index_2.0'];
if (!value || value === '-1') return -1;
const num = parseInt(value, 10);
return isNaN(num) ? -1 : num;
})
// 获取消费金额显示(直接显示金额区间)
const getConsumptionAmount = (score) => {
if (score === -1) return '无法评估'
const amountMap = {
100: '2,000 - 4,000',
200: '2,000 - 4,000',
300: '4,000 - 6,000',
400: '6,000 - 8,000',
500: '8,000 - 10,000',
600: '10,000 - 12,000',
700: '12,000 - 15,000',
800: '15,000 - 20,000',
900: '20,000 - 25,000',
1000: '25,000+'
}
return amountMap[score] || '数据异常'
}
// 消费能力描述
const getConsumptionDescription = (score) => {
if (score === -1) return '暂未发现消费能力信息'
const descriptionMap = {
100: '基础消费能力',
200: '基础消费能力',
300: '中等消费能力',
400: '中等消费能力',
500: '良好消费能力',
600: '良好消费能力',
700: '较强消费能力',
800: '较强消费能力',
900: '很强消费能力',
1000: '很强消费能力'
}
return descriptionMap[score] || '数据异常'
}
// 等级进度条样式
const getLevelBarStyle = (score) => {
if (score === -1) {
return {
width: '0%',
background: '#94a3b8'
}
}
// 计算百分比100分=10%, 200分=20%, ..., 1000分=100%
const percentage = (score / 1000) * 100
// 统一使用蓝色渐变
return {
width: percentage + '%',
background: 'linear-gradient(90deg, #3b82f6 0%, #2563eb 100%)'
}
}
// 进度条背景色样式
const getLevelBarBgStyle = (score) => {
// 统一使用淡蓝色背景
return {
background: '#eff6ff'
}
}
// 评估描述
const getAssessmentDescription = (score) => {
if (score === -1) {
return '根据个人消费能力等级分析,无法获取该用户的消费能力信息,无法进行评估。'
}
const descriptions = {
100: '根据个人消费能力等级分析,该用户月消费能力较低,消费水平有限。',
200: '根据个人消费能力等级分析,该用户月消费能力较低,消费水平有限。',
300: '根据个人消费能力等级分析,该用户月消费能力中等,消费水平良好。',
400: '根据个人消费能力等级分析,该用户月消费能力中等,消费水平良好。',
500: '根据个人消费能力等级分析,该用户月消费能力中等偏上,消费水平较强。',
600: '根据个人消费能力等级分析,该用户月消费能力中等偏上,消费水平较强。',
700: '根据个人消费能力等级分析,该用户月消费能力较高,消费水平很强。',
800: '根据个人消费能力等级分析,该用户月消费能力较高,消费水平很强。',
900: '根据个人消费能力等级分析,该用户月消费能力很高,消费水平顶级。',
1000: '根据个人消费能力等级分析,该用户月消费能力很高,消费水平顶级。'
}
return descriptions[score] || '数据异常,无法进行准确评估。'
}
// 市场对比分析
const getMarketComparison = (score) => {
if (score === -1) {
return '无消费能力信息,无法与市场平均水平进行对比。'
}
const comparisons = {
100: '低于市场平均消费水平,处于消费分布的底部区间。',
200: '低于市场平均消费水平,处于消费分布的中下区间。',
300: '接近市场平均消费水平,处于消费分布的中等区间。',
400: '接近市场平均消费水平,处于消费分布的中等区间。',
500: '高于市场平均消费水平,处于消费分布的中上区间。',
600: '高于市场平均消费水平,处于消费分布的中上区间。',
700: '明显高于市场平均消费水平,处于消费分布的上层区间。',
800: '显著高于市场平均消费水平,处于消费分布的高层区间。',
900: '远高于市场平均消费水平,处于消费分布的顶部区间。',
1000: '超越市场绝大多数消费水平,处于消费分布的顶级区间。'
}
return comparisons[score] || '数据异常,无法进行市场对比。'
}
// 消费能力分析
const getConsumptionCapacity = (score) => {
if (score === -1) {
return '缺乏消费能力信息,月消费能力存在不确定性,需要谨慎评估。'
}
const capacities = {
100: '月消费能力较低,消费水平有限,建议理性消费。',
200: '月消费能力较低,消费水平有限,建议理性消费。',
300: '月消费能力稳定,消费水平良好,具备一定的消费潜力。',
400: '月消费能力稳定,消费水平良好,具备一定的消费潜力。',
500: '月消费能力较高,消费水平较强,可以支持中等消费。',
600: '月消费能力较高,消费水平较强,可以支持中等消费。',
700: '月消费能力很强,消费水平很高,可以支持较高消费。',
800: '月消费能力很强,消费水平很高,可以支持较高消费。',
900: '月消费能力顶级,消费水平极高,可以支持高端消费。',
1000: '月消费能力顶级,消费水平极高,可以支持顶级消费。'
}
return capacities[score] || '数据异常,无法进行消费能力分析。'
}
// 指示器样式
const getIndicatorStyle = (score) => {
if (score === -1) return { width: '0%', background: 'transparent' }
// 100分=0%, 1000分=100%
const percentage = ((score - 100) / 900) * 100
return {
width: percentage + '%',
background: `linear-gradient(90deg, #93c5fd 0%, #3b82f6 50%, #1d4ed8 100%)`
}
}
// 标记位置
const getMarkerPosition = (score) => {
if (score === -1) return { left: '0%' }
// 100分=0%, 1000分=100%
const percentage = ((score - 100) / 900) * 100
return {
left: percentage + '%'
}
}
// 计算风险评分0-100分分数越高越安全
const riskScore = computed(() => {
if (score.value === -1) return 30 // 未命中,风险较高
// 100分对应30分1000分对应100分
return 30 + ((score.value - 100) / 900) * 70
});
// 使用 composable 通知父组件风险评分
useRiskNotifier(props, riskScore);
// 暴露给父组件
defineExpose({
riskScore
});
</script>
<style scoped>
/* 金额数字样式 */
.amount-number {
color: #333333;
font-weight: bold;
}
.amount-unit {
font-size: 0.5em;
color: #999999;
margin-left: 4px;
}
/* 进度条 */
.level-bar {
height: 12px;
border-radius: 8px;
overflow: hidden;
}
.level-fill {
height: 100%;
border-radius: 4px;
transition: all 0.6s ease;
}
/* 评估卡片 */
.assessment-card {
padding: 16px;
border-radius: 8px;
margin-bottom: 16px;
border: 1px solid;
}
/* 评估卡片统一样式 */
.assessment-card {
background: #f8fafc;
border-color: #e2e8f0;
}
/* 对比指示器 */
.comparison-indicator {
margin-top: 12px;
}
.indicator-bar {
position: relative;
height: 6px;
border-radius: 3px;
margin-bottom: 8px;
background: linear-gradient(90deg, #93c5fd 0%, #3b82f6 50%, #1d4ed8 100%);
}
.indicator-fill {
height: 100%;
border-radius: 3px;
transition: all 0.5s ease;
background: transparent;
}
.indicator-marker {
position: absolute;
top: -26px;
transform: translateX(-50%);
display: flex;
flex-direction: column;
align-items: center;
}
.marker-image {
width: 24px;
margin-bottom: 0px;
}
.marker-dot {
width: 8px;
height: 8px;
background: white;
border-radius: 50%;
box-shadow: 0px 4px 4px 0px #00000040;
}
.indicator-labels {
display: flex;
justify-content: space-between;
font-size: 0.7rem;
color: #9ca3af;
}
</style>