Files
report_viewer/src/ui/DWBG7F3A/components/MultipleApplicationSection.vue

520 lines
22 KiB
Vue
Raw Normal View History

2025-11-17 12:49:59 +08:00
<template>
<div class="card multiple-application-section">
<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/sjqsfx.png" alt="多头申请" class="w-8 h-8 object-contain" />
</div>
<span class="font-bold text-gray-800">多头申请</span>
</div>
<div class="mt-4">
<!-- 申请概览 -->
<div class="mb-6">
<LTitle title="申请概览" />
<div class="grid grid-cols-2 gap-4 p-4">
<div class="bg-blue-50 rounded-lg p-4 text-center border border-[#2B79EE8F]">
<div class="text-2xl font-bold text-[#1FBE5D]">
{{ getValue(data.applicationCounts?.['7d']?.total) }}
</div>
<div class="text-sm text-gray-600 mt-1">近7天申请次数</div>
</div>
<div class="bg-blue-50 rounded-lg p-4 text-center border border-[#2B79EE8F]">
<div class="text-2xl font-bold text-[#1FBE5D]">
{{ getValue(data.platformCounts?.['7d']?.total) }}
</div>
<div class="text-sm text-gray-600 mt-1">近7天申请平台数</div>
</div>
</div>
</div>
<!-- 申请次数时间分布图表 -->
<div class="mb-6">
<LTitle title="申请次数时间分布" />
<div class="mb-4 h-64">
<v-chart class="chart-container" :option="applicationCountChartOption" autoresize />
</div>
</div>
<!-- 行业次数统计 -->
<div class="mb-6">
<LTitle title="行业次数统计" />
<div class="bg-white px-4 py-2">
<van-tabs v-model:active="activeTab1" color="var(--color-primary)">
<van-tab v-for="(tab, index) in recentTabs" :key="tab.key" :title="tab.name">
<div class="p-4">
<div class="space-y-2">
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">总次数</span>
<span class="text-[#333333] font-bold">{{ getValue(data.applicationCounts?.[tab.key]?.total) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">银行</span>
<span class="text-[#333333] font-bold">{{ getValue(data.applicationCounts?.[tab.key]?.bank) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">持牌消金</span>
<span class="text-[#333333] font-bold">{{ getValue(data.applicationCounts?.[tab.key]?.licensedConsumer) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">互金</span>
<span class="text-[#333333] font-bold">{{ getValue(data.applicationCounts?.[tab.key]?.fintech) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">金融科技</span>
<span class="text-[#333333] font-bold">{{ getValue(data.applicationCounts?.[tab.key]?.tech) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">其他</span>
<span class="text-[#333333] font-bold">{{ getValue(data.applicationCounts?.[tab.key]?.other) }} </span>
</div>
</div>
</div>
</van-tab>
</van-tabs>
</div>
</div>
<!-- 行业平台数统计 -->
<div class="mb-6">
<LTitle title="行业平台数统计" />
<div class="bg-white px-4 py-2">
<van-tabs v-model:active="activeTab2" color="var(--color-primary)">
<van-tab v-for="(tab, index) in recentTabs" :key="tab.key" :title="tab.name">
<div class="p-4">
<div class="space-y-2">
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">总平台数</span>
<span class="text-[#333333] font-bold">{{ getValue(data.platformCounts?.[tab.key]?.total) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">银行</span>
<span class="text-[#333333] font-bold">{{ getValue(data.platformCounts?.[tab.key]?.bank) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">持牌消金</span>
<span class="text-[#333333] font-bold">{{ getValue(data.platformCounts?.[tab.key]?.licensedConsumer) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">互金</span>
<span class="text-[#333333] font-bold">{{ getValue(data.platformCounts?.[tab.key]?.fintech) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">金融科技</span>
<span class="text-[#333333] font-bold">{{ getValue(data.platformCounts?.[tab.key]?.tech) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">其他</span>
<span class="text-[#333333] font-bold">{{ getValue(data.platformCounts?.[tab.key]?.other) }} </span>
</div>
</div>
</div>
</van-tab>
</van-tabs>
</div>
</div>
<!-- 白天/凌晨申请统计 -->
<div class="mb-6">
<LTitle title="白天/凌晨申请统计" />
<div class="bg-white px-4 py-2">
<van-tabs v-model:active="activeTab3" color="var(--color-primary)">
<van-tab v-for="(tab, index) in recentTabs" :key="tab.key" :title="tab.name">
<div class="p-4">
<div class="space-y-2">
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">总白天次数</span>
<span class="text-[#333333] font-bold">{{ getValue(data.dayNightCounts?.day?.[tab.key]) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">总凌晨次数</span>
<span class="text-[#333333] font-bold">{{ getValue(data.dayNightCounts?.night?.[tab.key]) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">银行白天次数</span>
<span class="text-[#333333] font-bold">{{ getValue(data.bankDayNightCounts?.day?.[tab.key]) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">银行凌晨次数</span>
<span class="text-[#333333] font-bold">{{ getValue(data.bankDayNightCounts?.night?.[tab.key]) }} </span>
</div>
</div>
</div>
</van-tab>
</van-tabs>
</div>
2025-12-18 15:39:43 +08:00
<div class="text-sm text-gray-500 px-4">白天8-23夜晚0点-7</div>
2025-11-17 12:49:59 +08:00
</div>
<!-- 白天/凌晨申请平台数统计 -->
<div class="mb-6">
<LTitle title="白天/凌晨申请平台数统计" />
<div class="bg-white px-4 py-2">
<van-tabs v-model:active="activeTab4" color="var(--color-primary)">
<van-tab v-for="(tab, index) in recentTabs" :key="tab.key" :title="tab.name">
<div class="p-4">
<div class="space-y-2">
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">总白天平台数</span>
<span class="text-[#333333] font-bold">{{ getValue(data.dayNightPlatforms?.day?.[tab.key]) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">总凌晨平台数</span>
<span class="text-[#333333] font-bold">{{ getValue(data.dayNightPlatforms?.night?.[tab.key]) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">银行白天平台数</span>
<span class="text-[#333333] font-bold">{{ getValue(data.bankDayNightPlatforms?.day?.[tab.key]) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">银行凌晨平台数</span>
<span class="text-[#333333] font-bold">{{ getValue(data.bankDayNightPlatforms?.night?.[tab.key]) }} </span>
</div>
</div>
</div>
</van-tab>
</van-tabs>
</div>
</div>
<!-- 新增平台数统计 -->
<div class="mb-6">
<LTitle title="新增平台数统计" />
<div class="bg-white px-4 py-2">
<van-tabs v-model:active="activeTab5" color="var(--color-primary)">
<van-tab title="7天">
<div class="p-4">
<div class="space-y-2">
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">相对过去30天</span>
<span class="text-[#333333] font-bold">{{ getValue(data.newBankPlatforms?.['7d_vs_30d']) }}/{{ getValue(data.newTotalPlatforms?.['7d_vs_30d']) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">相对过去90天</span>
<span class="text-[#333333] font-bold">{{ getValue(data.newBankPlatforms?.['7d_vs_90d']) }}/{{ getValue(data.newTotalPlatforms?.['7d_vs_90d']) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">相对过去180天</span>
<span class="text-[#333333] font-bold">{{ getValue(data.newBankPlatforms?.['7d_vs_180d']) }}/{{ getValue(data.newTotalPlatforms?.['7d_vs_180d']) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">相对过去360天</span>
<span class="text-[#333333] font-bold">{{ getValue(data.newBankPlatforms?.['7d_vs_360d']) }}/{{ getValue(data.newTotalPlatforms?.['7d_vs_360d']) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">相对过去720天</span>
<span class="text-[#333333] font-bold">{{ getValue(data.newBankPlatforms?.['7d_vs_720d']) }}/{{ getValue(data.newTotalPlatforms?.['7d_vs_720d']) }} </span>
</div>
</div>
</div>
</van-tab>
<van-tab title="15天">
<div class="p-4">
<div class="space-y-2">
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">相对过去30天</span>
<span class="text-[#333333] font-bold">{{ getValue(data.newBankPlatforms?.['15d_vs_30d']) }}/{{ getValue(data.newTotalPlatforms?.['15d_vs_30d']) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">相对过去90天</span>
<span class="text-[#333333] font-bold">{{ getValue(data.newBankPlatforms?.['15d_vs_90d']) }}/{{ getValue(data.newTotalPlatforms?.['15d_vs_90d']) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">相对过去180天</span>
<span class="text-[#333333] font-bold">{{ getValue(data.newBankPlatforms?.['15d_vs_180d']) }}/{{ getValue(data.newTotalPlatforms?.['15d_vs_180d']) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">相对过去360天</span>
<span class="text-[#333333] font-bold">{{ getValue(data.newBankPlatforms?.['15d_vs_360d']) }}/{{ getValue(data.newTotalPlatforms?.['15d_vs_360d']) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">相对过去720天</span>
<span class="text-[#333333] font-bold">{{ getValue(data.newBankPlatforms?.['15d_vs_720d']) }}/{{ getValue(data.newTotalPlatforms?.['15d_vs_720d']) }} </span>
</div>
</div>
</div>
</van-tab>
<van-tab title="30天">
<div class="p-4">
<div class="space-y-2">
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">相对过去90天</span>
<span class="text-[#333333] font-bold">{{ getValue(data.newBankPlatforms?.['30d_vs_90d']) }}/{{ getValue(data.newTotalPlatforms?.['30d_vs_90d']) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">相对过去180天</span>
<span class="text-[#333333] font-bold">{{ getValue(data.newBankPlatforms?.['30d_vs_180d']) }}/{{ getValue(data.newTotalPlatforms?.['30d_vs_180d']) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">相对过去360天</span>
<span class="text-[#333333] font-bold">{{ getValue(data.newBankPlatforms?.['30d_vs_360d']) }}/{{ getValue(data.newTotalPlatforms?.['30d_vs_360d']) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">相对过去720天</span>
<span class="text-[#333333] font-bold">{{ getValue(data.newBankPlatforms?.['30d_vs_720d']) }}/{{ getValue(data.newTotalPlatforms?.['30d_vs_720d']) }} </span>
</div>
</div>
</div>
</van-tab>
</van-tabs>
</div>
2025-12-18 15:39:43 +08:00
<div class="text-sm text-gray-500 px-4 mt-2">格式为 银行平台/总平台</div>
2025-11-17 12:49:59 +08:00
</div>
<!-- 查询天数差 -->
<div class="mb-6">
<LTitle title="查询天数差" />
<div class="space-y-2 p-4">
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">最早一次查询距今</span>
<span class="text-[#333333] font-bold">{{ getValue(queryDays?.earliestQueryDays) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">最近一次查询距今</span>
<span class="text-[#333333] font-bold">{{ getValue(queryDays?.latestQueryDays) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">最早一次在银行机构距今</span>
<span class="text-[#333333] font-bold">{{ getValue(queryDays?.earliestBankDays) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">最近一次在银行机构距今</span>
<span class="text-[#333333] font-bold">{{ getValue(queryDays?.latestBankDays) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">最早一次在非银机构距今</span>
<span class="text-[#333333] font-bold">{{ getValue(queryDays?.earliestNonBankDays) }} </span>
</div>
<div class="flex justify-between items-center text-sm">
<span class="text-gray-600">最近一次在非银机构距今</span>
<span class="text-[#333333] font-bold">{{ getValue(queryDays?.latestNonBankDays) }} </span>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { computed, ref } from 'vue'
import LTitle from '@/components/LTitle.vue'
import VChart from 'vue-echarts'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { BarChart } from 'echarts/charts'
import {
TitleComponent,
TooltipComponent,
LegendComponent,
GridComponent
} from 'echarts/components'
// 注册ECharts组件
use([
CanvasRenderer,
BarChart,
TitleComponent,
TooltipComponent,
LegendComponent,
GridComponent
])
const props = defineProps({
data: {
type: Object,
default: () => ({})
},
queryDays: {
type: Object,
default: () => ({})
}
})
// Tab 相关状态
const activeTab1 = ref(0)
const activeTab2 = ref(0)
const activeTab3 = ref(0)
const activeTab4 = ref(0)
const activeTab5 = ref(0)
// 近期活动 tab 数据
const recentTabs = [
{ name: '7天', key: '7d' },
{ name: '15天', key: '15d' },
{ name: '30天', key: '30d' },
{ name: '60天', key: '60d' },
{ name: '90天', key: '90d' },
{ name: '180天', key: '180d' },
{ name: '360天', key: '360d' },
{ name: '720天', key: '720d' },
]
const getValue = (value) => {
if (value === undefined || value === null || value === '') return '-'
return value
}
// 申请次数图表配置
const applicationCountChartOption = computed(() => {
const periods = ['7天', '15天', '30天', '60天', '90天', '180天', '360天', '720天']
const keys = ['7d', '15d', '30d', '60d', '90d', '180d', '360d', '720d']
const totalData = keys.map(key => getValue(props.data?.applicationCounts?.[key]?.total) || 0)
const bankData = keys.map(key => getValue(props.data?.applicationCounts?.[key]?.bank) || 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
}
},
legend: {
data: ['总次数', '银行'],
top: '5%',
textStyle: {
fontSize: 12
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
top: '20%',
containLabel: true
},
xAxis: {
type: 'category',
data: periods,
axisLabel: {
2025-12-18 15:39:43 +08:00
fontSize: 12,
2025-11-17 12:49:59 +08:00
color: '#6b7280',
rotate: 45
},
axisLine: {
lineStyle: {
color: '#e5e7eb'
}
}
},
yAxis: {
type: 'value',
axisLabel: {
2025-12-18 15:39:43 +08:00
fontSize: 12,
2025-11-17 12:49:59 +08:00
color: '#6b7280',
formatter: '{value} 次'
},
splitLine: {
lineStyle: {
color: '#f3f4f6'
}
}
},
series: [
{
name: '总次数',
type: 'bar',
data: totalData,
barWidth: '25%',
barMinHeight: 3,
itemStyle: {
color: '#2B79EE',
borderRadius: [4, 4, 0, 0]
},
emphasis: {
itemStyle: {
color: '#1e5bb8'
}
}
},
{
name: '银行',
type: 'bar',
data: bankData,
barWidth: '25%',
barMinHeight: 3,
itemStyle: {
color: '#61D2F4',
borderRadius: [4, 4, 0, 0]
},
emphasis: {
itemStyle: {
color: '#4bb8d4'
}
}
}
]
}
})
</script>
<style lang="scss" scoped>
.card {
background: #ffffff;
}
.chart-container {
width: 100%;
height: 100%;
}
.multiple-application-section :deep(.van-tabs) {
border: unset !important;
}
.multiple-application-section :deep(.van-tabs__wrap) {
height: 32px !important;
background-color: transparent !important;
padding: 0 !important;
border-bottom: 1px solid #DDDDDD !important;
}
.multiple-application-section :deep(.van-tabs__nav) {
background-color: transparent !important;
gap: 0 !important;
height: 32px !important;
border: unset !important;
}
.multiple-application-section :deep(.van-tabs__nav--card) {
border: unset !important;
}
.multiple-application-section :deep(.van-tab) {
color: #999999 !important;
font-size: 14px !important;
font-weight: 400 !important;
border-right: unset !important;
background-color: transparent !important;
border-radius: unset !important;
max-width: 80px !important;
}
.multiple-application-section :deep(.van-tab--card) {
color: #999999 !important;
border-right: unset !important;
background-color: transparent !important;
border-radius: unset !important;
}
.multiple-application-section :deep(.van-tab--active) {
color: var(--van-theme-primary) !important;
background-color: unset !important;
}
.multiple-application-section :deep(.van-tabs__line) {
height: 4px !important;
border-radius: 1px !important;
background-color: var(--van-theme-primary) !important;
width: 20px;
border-radius: 14px;
}
</style>