Files
report_viewer/src/ui/DWBG7F3A/components/MultipleApplicationSection.vue
2025-12-18 15:39:43 +08:00

520 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>
<div class="text-sm text-gray-500 px-4">白天8-23夜晚0点-7</div>
</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>
<div class="text-sm text-gray-500 px-4 mt-2">格式为 银行平台/总平台</div>
</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: {
fontSize: 12,
color: '#6b7280',
rotate: 45
},
axisLine: {
lineStyle: {
color: '#e5e7eb'
}
}
},
yAxis: {
type: 'value',
axisLabel: {
fontSize: 12,
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>