first commit

This commit is contained in:
2025-11-17 12:49:59 +08:00
commit 89fd3c8bd9
238 changed files with 51533 additions and 0 deletions

View File

@@ -0,0 +1,459 @@
<template>
<div class="apply-report-section bg-white rounded-lg border border-gray-200">
<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/sjqsfx.png" alt="申请行为详情" class="w-8 h-8 object-contain" />
</div>
<span class="font-bold text-gray-800">申请行为详情</span>
</div>
<div class="p-4">
<!-- 核心指标 -->
<div class="grid grid-cols-2 gap-4 mb-6">
<!-- 申请准入分 -->
<div class="rounded-lg border border-[#2B79EE8F] bg-[#2B79EE1A] p-4">
<div class="text-sm font-medium text-gray-700 mb-2 text-center">申请准入分</div>
<div class="h-40">
<v-chart class="chart-container" :option="applyScoreGaugeOption" autoresize />
</div>
</div>
<!-- 申请准入置信度 -->
<div class="rounded-lg border border-[#2B79EE8F] bg-[#2B79EE1A] p-4">
<div class="text-sm font-medium text-gray-700 mb-2 text-center">申请准入置信度</div>
<div class="h-40">
<v-chart class="chart-container" :option="applyConfidenceGaugeOption" autoresize />
</div>
</div>
</div>
<!-- 申请命中情况 -->
<LTitle title="申请命中情况" />
<div class="grid grid-cols-2 gap-4 mb-6 mt-3">
<div class="bg-gray-50 rounded-lg p-3">
<div class="text-sm text-gray-600 mb-1">申请命中机构数</div>
<div class="text-lg font-bold text-gray-800">{{ getValue(data.A22160003, '0') }} </div>
</div>
<div class="bg-gray-50 rounded-lg p-3">
<div class="text-sm text-gray-600 mb-1">申请命中消金类机构数</div>
<div class="text-lg font-bold text-gray-800">{{ getValue(data.A22160004, '0') }} </div>
</div>
<div class="bg-gray-50 rounded-lg p-3">
<div class="text-sm text-gray-600 mb-1">申请命中网络贷款类机构数</div>
<div class="text-lg font-bold text-gray-800">{{ getValue(data.A22160005, '0') }} </div>
</div>
</div>
<!-- 机构查询统计 -->
<LTitle title="机构查询统计" />
<div class="mt-3">
<div class="bg-gray-50 rounded-lg p-4 mb-4">
<div class="flex justify-between items-center mb-3">
<span class="text-sm text-gray-600">机构总查询次数</span>
<span class="text-lg font-bold text-gray-800">{{ getValue(data.A22160006, '0') }} </span>
</div>
<div class="flex justify-between items-center mb-3">
<span class="text-sm text-gray-600">最近一次查询时间</span>
<span class="text-lg font-bold text-gray-800">{{ formatTime(data.A22160007) }}</span>
</div>
</div>
<div class="grid grid-cols-3 gap-3">
<div class="bg-blue-50 rounded-lg p-3 text-center border border-[#2B79EE8F]">
<div class="text-xl font-bold text-[#2B79EE] mb-1">{{ getValue(data.A22160008, '0') }}</div>
<div class="text-xs text-gray-600">近1个月查询笔数</div>
</div>
<div class="bg-blue-50 rounded-lg p-3 text-center border border-[#2B79EE8F]">
<div class="text-xl font-bold text-[#2B79EE] mb-1">{{ getValue(data.A22160009, '0') }}</div>
<div class="text-xs text-gray-600">近3个月查询笔数</div>
</div>
<div class="bg-blue-50 rounded-lg p-3 text-center border border-[#2B79EE8F]">
<div class="text-xl font-bold text-[#2B79EE] mb-1">{{ getValue(data.A22160010, '0') }}</div>
<div class="text-xs text-gray-600">近6个月查询笔数</div>
</div>
</div>
<!-- 查询次数趋势图 -->
<div class="mb-4 mt-4">
<LTitle title="查询次数趋势" />
<div class="h-64 mt-3">
<v-chart class="chart-container" :option="queryTrendChartOption" autoresize />
</div>
</div>
</div>
</div>
<!-- 温馨提示 -->
<Remark
content="申请行为详情展示申请人在各金融机构的申请记录和查询行为,包括申请准入分、命中机构数、机构查询次数等指标。申请行为反映了申请人的借贷需求和信用活跃度。频繁的申请可能暗示资金需求紧张或信用状况不佳。建议关注申请命中机构数和查询次数,过多的申请可能影响信用评分。" />
</div>
</template>
<script setup>
import { computed } from 'vue'
import LTitle from '@/components/LTitle.vue'
import Remark from '@/components/Remark.vue'
import VChart from 'vue-echarts'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { BarChart, GaugeChart } from 'echarts/charts'
import {
TitleComponent,
TooltipComponent,
LegendComponent,
GridComponent
} from 'echarts/components'
import { formatConfidence, formatTime, getValue } from '../utils/formatUtils'
// 注册ECharts组件
use([
CanvasRenderer,
BarChart,
GaugeChart,
TitleComponent,
TooltipComponent,
LegendComponent,
GridComponent
])
const props = defineProps({
data: {
type: Object,
default: () => ({})
}
})
// 申请准入分仪表盘配置1-1000分分数越高风险越大
const applyScoreGaugeOption = computed(() => {
const score = parseInt(getValue(props.data.A22160001, '0')) || 0
// 转换为0-100的百分比用于仪表盘显示
const percentage = (score / 1000) * 100
// 根据分数确定颜色(分数越高风险越大)
let color = '#52c41a' // 绿色 - 低风险
if (score > 800) {
color = '#f5222d' // 红色 - 高风险
} else if (score > 600) {
color = '#fa8c16' // 橙色 - 中高风险
} else if (score > 400) {
color = '#faad14' // 黄色 - 中等风险
}
return {
series: [
{
type: 'gauge',
startAngle: 180,
endAngle: 0,
min: 0,
max: 100,
radius: '75%',
center: ['50%', '75%'],
itemStyle: {
color: color,
shadowBlur: 4,
shadowColor: color,
shadowOffsetX: 0,
shadowOffsetY: 0,
},
progress: {
show: true,
width: 14,
roundCap: true,
clip: false,
},
axisLine: {
roundCap: true,
lineStyle: {
width: 14,
color: [
[percentage / 100, color],
[1, '#e5e7eb']
]
}
},
axisTick: {
show: true,
distance: -28,
length: 6,
splitNumber: 10,
lineStyle: {
width: 1.5,
color: '#999',
opacity: 0.5
}
},
splitLine: {
show: true,
distance: -34,
length: 10,
splitNumber: 5,
lineStyle: {
width: 2,
color: '#999',
opacity: 0.7
}
},
axisLabel: {
show: true,
distance: -18,
fontSize: 10,
color: '#666',
formatter: function(value) {
if (value === 0) return '0'
if (value === 25) return '250'
if (value === 50) return '500'
if (value === 75) return '750'
if (value === 100) return '1000'
return ''
}
},
pointer: {
show: false
},
detail: {
valueAnimation: true,
fontSize: 24,
fontWeight: 'bold',
color: color,
offsetCenter: [0, '-5%'],
formatter: () => `${score}`,
rich: {
value: {
fontSize: 24,
fontWeight: 'bold',
color: color,
lineHeight: 28
},
unit: {
fontSize: 16,
color: '#666',
padding: [0, 0, 0, 4]
}
}
},
data: [
{
value: percentage
}
],
title: {
show: true,
fontSize: 13,
color: '#666',
offsetCenter: [0, '25%'],
formatter: () => '申请准入分'
}
}
]
}
})
// 申请准入置信度仪表盘配置50-100
const applyConfidenceGaugeOption = computed(() => {
const confidence = parseInt(getValue(props.data.A22160002, '0')) || 0
// 转换为0-100的百分比置信度范围是50-100所以需要映射
const percentage = confidence >= 50 ? ((confidence - 50) / 50) * 100 : 0
// 根据置信度确定颜色
let color = '#52c41a' // 绿色 - 高置信度
if (confidence < 60) {
color = '#faad14' // 黄色 - 中等置信度
} else if (confidence < 70) {
color = '#fa8c16' // 橙色 - 较低置信度
}
return {
series: [
{
type: 'gauge',
startAngle: 180,
endAngle: 0,
min: 0,
max: 100,
radius: '85%',
center: ['50%', '75%'],
itemStyle: {
color: color,
shadowBlur: 8,
shadowColor: color,
},
progress: {
show: true,
width: 18,
roundCap: true,
},
axisLine: {
roundCap: true,
lineStyle: {
width: 18,
color: [
[percentage / 100, color],
[1, '#e5e7eb']
]
}
},
axisTick: {
show: true,
distance: -25,
length: 6,
splitNumber: 5,
lineStyle: {
width: 2,
color: '#999',
opacity: 0.5
}
},
splitLine: {
show: true,
distance: -30,
length: 10,
splitNumber: 4,
lineStyle: {
width: 2,
color: '#999',
opacity: 0.7
}
},
axisLabel: {
show: true,
distance: -15,
fontSize: 11,
color: '#666',
formatter: function(value) {
// 将百分比映射回置信度值
const confValue = Math.round(50 + (value / 100) * 50)
if (value === 0) return '50'
if (value === 25) return '62'
if (value === 50) return '75'
if (value === 75) return '87'
if (value === 100) return '100'
return ''
}
},
pointer: {
show: false
},
detail: {
valueAnimation: true,
fontSize: 24,
fontWeight: 'bold',
color: color,
offsetCenter: [0, '-5%'],
formatter: () => `${confidence}%`,
rich: {
value: {
fontSize: 24,
fontWeight: 'bold',
color: color,
lineHeight: 28
}
}
},
data: [
{
value: percentage
}
],
title: {
show: true,
fontSize: 14,
color: '#666',
offsetCenter: [0, '25%'],
formatter: () => '申请准入置信度'
}
}
]
}
})
// 查询次数趋势图配置
const queryTrendChartOption = computed(() => {
const periods = ['近1个月', '近3个月', '近6个月']
const queryData = [
parseInt(getValue(props.data.A22160008, '0')) || 0,
parseInt(getValue(props.data.A22160009, '0')) || 0,
parseInt(getValue(props.data.A22160010, '0')) || 0
]
return {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
formatter: function (params) {
let result = params[0].name + '<br/>'
params.forEach(item => {
result += `${item.seriesName}: ${item.value} 次<br/>`
})
return result
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
top: '10%',
containLabel: true
},
xAxis: {
type: 'category',
data: periods,
axisLabel: {
fontSize: 12,
color: '#6b7280'
},
axisLine: {
lineStyle: {
color: '#e5e7eb'
}
}
},
yAxis: {
type: 'value',
axisLabel: {
fontSize: 11,
color: '#6b7280',
formatter: '{value} 次'
},
splitLine: {
lineStyle: {
color: '#f3f4f6'
}
}
},
series: [
{
name: '查询笔数',
type: 'bar',
data: queryData,
barWidth: '40%',
itemStyle: {
color: '#2B79EE',
borderRadius: [4, 4, 0, 0]
},
emphasis: {
itemStyle: {
color: '#1e5bb8'
}
},
label: {
show: true,
position: 'top',
fontSize: 11,
color: '#333'
}
}
]
}
})
</script>
<style scoped>
.chart-container {
width: 100%;
height: 100%;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,456 @@
<template>
<div class="current-report-section bg-white rounded-lg border border-gray-200">
<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/gl.png" alt="信用详情" class="w-8 h-8 object-contain" />
</div>
<span class="font-bold text-gray-800">信用详情</span>
</div>
<div class="p-4">
<!-- 网络贷款类信用 -->
<LTitle title="网络贷款类信用" />
<div class="mt-3 mb-6">
<div class="space-y-4 mb-4">
<!-- 网贷授信额度 -->
<div class="rounded-lg border border-[#2B79EE8F] bg-[#2B79EE1A] p-4 text-center">
<div class="text-xl font-bold text-[#2B79EE] mb-1">
{{ formatCreditAmount(data.C22180001) }}
</div>
<div class="text-sm font-medium text-gray-700 mb-1">网贷授信额度</div>
</div>
<!-- 网贷额度置信度 -->
<div class="rounded-lg border border-[#2B79EE8F] bg-[#2B79EE1A] p-4">
<div class="text-sm font-medium text-gray-700 mb-2 text-center">网贷额度置信度</div>
<div class="h-40">
<v-chart class="chart-container" :option="p2pConfidenceGaugeOption" autoresize />
</div>
</div>
</div>
<div class="bg-gray-50 rounded-lg p-4 space-y-3">
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">网络贷款类机构数</span>
<span class="text-lg font-bold text-gray-800">{{ getValue(data.C22180003, '0') }} </span>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">网络贷款类产品数</span>
<span class="text-lg font-bold text-gray-800">{{ getValue(data.C22180004, '0') }} </span>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">网络贷款机构最大授信额度</span>
<span class="text-lg font-bold text-gray-800">{{ formatCreditAmount(data.C22180005) }}</span>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">网络贷款机构平均授信额度</span>
<span class="text-lg font-bold text-gray-800">{{ formatCreditAmount(data.C22180006) }}</span>
</div>
</div>
<!-- 授信额度对比图 -->
<div class="mb-6">
<LTitle title="授信额度对比" />
<div class="h-64 mt-3">
<v-chart class="chart-container" :option="creditAmountChartOption" autoresize />
</div>
</div>
</div>
<!-- 消金贷款类信用 -->
<LTitle title="消金贷款类信用" />
<div class="mt-3 mb-6">
<div class="space-y-4 mb-4">
<!-- 消金建议授信额度 -->
<div class="rounded-lg border border-[#1FBE5D8F] bg-[#1FBE5D1A] p-4 text-center">
<div class="text-xl font-bold text-[#1FBE5D] mb-1">
{{ formatCreditAmount(data.C22180011) }}
</div>
<div class="text-sm font-medium text-gray-700 mb-1">消金建议授信额度</div>
</div>
<!-- 消金额度置信度 -->
<div class="rounded-lg border border-[#1FBE5D8F] bg-[#1FBE5D1A] p-4">
<div class="text-sm font-medium text-gray-700 mb-2 text-center">消金额度置信度</div>
<div class="h-40">
<v-chart class="chart-container" :option="consumerConfidenceGaugeOption" autoresize />
</div>
</div>
</div>
<div class="bg-gray-50 rounded-lg p-4 space-y-3">
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">消金贷款类机构数</span>
<span class="text-lg font-bold text-gray-800">{{ getValue(data.C22180007, '0') }} </span>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">消金贷款类产品数</span>
<span class="text-lg font-bold text-gray-800">{{ getValue(data.C22180008, '0') }} </span>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">消金贷款类机构最大授信额度</span>
<span class="text-lg font-bold text-gray-800">{{ formatCreditAmount(data.C22180009) }}</span>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">消金贷款类机构平均授信额度</span>
<span class="text-lg font-bold text-gray-800">{{ formatCreditAmount(data.C22180010) }}</span>
</div>
</div>
</div>
</div>
<!-- 温馨提示 -->
<Remark
content="信用详情展示申请人在网络贷款和消金贷款领域的授信情况,包括授信额度、机构数、产品数等指标。授信额度反映了金融机构对申请人信用状况的评估,额度越高通常表示信用状况越好。建议关注授信额度置信度,置信度越高表示评估结果越可靠。同时需要结合申请人的实际借贷行为和还款记录进行综合评估。" />
</div>
</template>
<script setup>
import { computed } from 'vue'
import LTitle from '@/components/LTitle.vue'
import Remark from '@/components/Remark.vue'
import VChart from 'vue-echarts'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { BarChart, GaugeChart } from 'echarts/charts'
import {
TitleComponent,
TooltipComponent,
LegendComponent,
GridComponent
} from 'echarts/components'
import { formatCreditAmount, formatConfidence, getValue } from '../utils/formatUtils'
// 注册ECharts组件
use([
CanvasRenderer,
BarChart,
GaugeChart,
TitleComponent,
TooltipComponent,
LegendComponent,
GridComponent
])
const props = defineProps({
data: {
type: Object,
default: () => ({})
}
})
// 网贷额度置信度仪表盘配置50-100
const p2pConfidenceGaugeOption = computed(() => {
const confidence = parseInt(getValue(props.data.C22180002, '0')) || 0
const percentage = confidence >= 50 ? ((confidence - 50) / 50) * 100 : 0
// 根据置信度确定颜色
let color = '#2B79EE' // 蓝色 - 高置信度
if (confidence < 60) {
color = '#faad14' // 黄色 - 中等置信度
} else if (confidence < 70) {
color = '#fa8c16' // 橙色 - 较低置信度
}
return {
series: [
{
type: 'gauge',
startAngle: 180,
endAngle: 0,
min: 0,
max: 100,
radius: '90%',
center: ['50%', '75%'],
itemStyle: {
color: color,
shadowBlur: 6,
shadowColor: color,
},
progress: {
show: true,
width: 18,
roundCap: true,
},
axisLine: {
roundCap: true,
lineStyle: {
width: 18,
color: [
[percentage / 100, color],
[1, '#e5e7eb']
]
}
},
axisTick: {
show: false
},
splitLine: {
show: false
},
axisLabel: {
show: false
},
pointer: {
show: false
},
detail: {
valueAnimation: true,
fontSize: 24,
fontWeight: 'bold',
color: color,
offsetCenter: [0, '-5%'],
formatter: '{value}%',
rich: {
value: {
fontSize: 24,
fontWeight: 'bold',
color: color,
lineHeight: 28
}
}
},
data: [
{
value: percentage
}
],
title: {
fontSize: 14,
color: '#666',
offsetCenter: [0, '25%'],
formatter: () => `${confidence}%`
}
}
]
}
})
// 消金额度置信度仪表盘配置50-100
const consumerConfidenceGaugeOption = computed(() => {
const confidence = parseInt(getValue(props.data.C22180012, '0')) || 0
const percentage = confidence >= 50 ? ((confidence - 50) / 50) * 100 : 0
// 根据置信度确定颜色
let color = '#1FBE5D' // 绿色 - 高置信度
if (confidence < 60) {
color = '#faad14' // 黄色 - 中等置信度
} else if (confidence < 70) {
color = '#fa8c16' // 橙色 - 较低置信度
}
return {
series: [
{
type: 'gauge',
startAngle: 180,
endAngle: 0,
min: 0,
max: 100,
radius: '90%',
center: ['50%', '75%'],
itemStyle: {
color: color,
shadowBlur: 6,
shadowColor: color,
},
progress: {
show: true,
width: 18,
roundCap: true,
},
axisLine: {
roundCap: true,
lineStyle: {
width: 18,
color: [
[percentage / 100, color],
[1, '#e5e7eb']
]
}
},
axisTick: {
show: false
},
splitLine: {
show: false
},
axisLabel: {
show: false
},
pointer: {
show: false
},
detail: {
valueAnimation: true,
fontSize: 24,
fontWeight: 'bold',
color: color,
offsetCenter: [0, '-5%'],
formatter: '{value}%',
rich: {
value: {
fontSize: 24,
fontWeight: 'bold',
color: color,
lineHeight: 28
}
}
},
data: [
{
value: percentage
}
],
title: {
fontSize: 14,
color: '#666',
offsetCenter: [0, '25%'],
formatter: () => `${confidence}%`
}
}
]
}
})
// 授信额度对比图配置
const creditAmountChartOption = computed(() => {
const categories = ['网贷', '消金']
const maxData = [
parseInt(getValue(props.data.C22180005, '0')) || 0,
parseInt(getValue(props.data.C22180009, '0')) || 0
]
const avgData = [
parseInt(getValue(props.data.C22180006, '0')) || 0,
parseInt(getValue(props.data.C22180010, '0')) || 0
]
return {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
formatter: function (params) {
let result = params[0].name + '<br/>'
params.forEach(item => {
const value = item.value >= 10000
? `${(item.value / 10000).toFixed(2)}万元`
: `${item.value}`
result += `${item.seriesName}: ${value}<br/>`
})
return result
}
},
legend: {
data: ['最大授信额度', '平均授信额度'],
top: '5%',
textStyle: {
fontSize: 12
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
top: '20%',
containLabel: true
},
xAxis: {
type: 'category',
data: categories,
axisLabel: {
fontSize: 12,
color: '#6b7280'
},
axisLine: {
lineStyle: {
color: '#e5e7eb'
}
}
},
yAxis: {
type: 'value',
axisLabel: {
fontSize: 11,
color: '#6b7280',
formatter: function (value) {
if (value >= 10000) {
return `${(value / 10000).toFixed(1)}`
}
return value
}
},
splitLine: {
lineStyle: {
color: '#f3f4f6'
}
}
},
series: [
{
name: '最大授信额度',
type: 'bar',
data: maxData,
barWidth: '30%',
itemStyle: {
color: '#2B79EE',
borderRadius: [4, 4, 0, 0]
},
emphasis: {
itemStyle: {
color: '#1e5bb8'
}
},
label: {
show: true,
position: 'top',
fontSize: 11,
color: '#333',
formatter: function (params) {
const value = params.value
return value >= 10000
? `${(value / 10000).toFixed(1)}`
: value
}
}
},
{
name: '平均授信额度',
type: 'bar',
data: avgData,
barWidth: '30%',
itemStyle: {
color: '#1FBE5D',
borderRadius: [4, 4, 0, 0]
},
emphasis: {
itemStyle: {
color: '#179e4d'
}
},
label: {
show: true,
position: 'top',
fontSize: 11,
color: '#333',
formatter: function (params) {
const value = params.value
return value >= 10000
? `${(value / 10000).toFixed(1)}`
: value
}
}
}
]
}
})
</script>
<style scoped>
.chart-container {
width: 100%;
height: 100%;
}
</style>