362 lines
9.5 KiB
Vue
362 lines
9.5 KiB
Vue
|
|
<script setup>
|
|||
|
|
import QiunDataCharts from '@/components/qiun-data-charts/qiun-data-charts.vue'
|
|||
|
|
|
|||
|
|
const props = defineProps({
|
|||
|
|
data: {
|
|||
|
|
type: Object,
|
|||
|
|
required: true,
|
|||
|
|
},
|
|||
|
|
})
|
|||
|
|
const { data } = props
|
|||
|
|
const tableData = ref([
|
|||
|
|
])
|
|||
|
|
const dateTableData = ref([
|
|||
|
|
])
|
|||
|
|
const options = ref([
|
|||
|
|
{ label: '近7日', value: 0 },
|
|||
|
|
{ label: '近1月', value: 1 },
|
|||
|
|
{ label: '近3月', value: 2 },
|
|||
|
|
{ label: '近6月', value: 3 },
|
|||
|
|
{ label: '近1年', value: 4 },
|
|||
|
|
])
|
|||
|
|
const dateOptions = ref([
|
|||
|
|
{ label: '近7日', value: 0 },
|
|||
|
|
{ label: '近1月', value: 1 },
|
|||
|
|
{ label: '近3月', value: 2 },
|
|||
|
|
{ label: '近6月', value: 3 },
|
|||
|
|
{ label: '近1年', value: 4 },
|
|||
|
|
])
|
|||
|
|
|
|||
|
|
const selectedOption = ref(0)
|
|||
|
|
const dateSelectedOption = ref(0)
|
|||
|
|
const chartData = ref({})
|
|||
|
|
|
|||
|
|
const opts = ref({
|
|||
|
|
|
|||
|
|
color: ['#FAC858', '#EE6666', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc'],
|
|||
|
|
padding: [15, 15, 0, 5],
|
|||
|
|
enableScroll: false,
|
|||
|
|
legend: {},
|
|||
|
|
xAxis: {
|
|||
|
|
disableGrid: true,
|
|||
|
|
},
|
|||
|
|
yAxis: {
|
|||
|
|
data: [
|
|||
|
|
{
|
|||
|
|
min: 0,
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
},
|
|||
|
|
extra: {
|
|||
|
|
column: {
|
|||
|
|
type: 'group',
|
|||
|
|
width: 15,
|
|||
|
|
activeBgColor: '#000000',
|
|||
|
|
activeBgOpacity: 0.08,
|
|||
|
|
linearType: 'custom',
|
|||
|
|
seriesGap: 5,
|
|||
|
|
linearOpacity: 0.5,
|
|||
|
|
barBorderCircle: true,
|
|||
|
|
customColor: [
|
|||
|
|
'#FA7D8D',
|
|||
|
|
'#EB88E2',
|
|||
|
|
],
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
)
|
|||
|
|
onMounted(() => {
|
|||
|
|
const seriesData = calculateTotalStats(data)
|
|||
|
|
tableData.value = typeTotalStats(data)
|
|||
|
|
dateTableData.value = dateTotalStats(data)
|
|||
|
|
const res = {
|
|||
|
|
categories: ['近7日', '近1月', '近3月', '近6月', '近1年'],
|
|||
|
|
series: [
|
|||
|
|
{
|
|||
|
|
name: '申请次数',
|
|||
|
|
data: seriesData.totalApplyCount,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: '申请的机构数',
|
|||
|
|
data: seriesData.totalOrgCount,
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
}
|
|||
|
|
chartData.value = JSON.parse(JSON.stringify(res))
|
|||
|
|
},
|
|||
|
|
)
|
|||
|
|
function calculateTotalStats(data) {
|
|||
|
|
// 时间维度映射
|
|||
|
|
const timeDimensions = {
|
|||
|
|
d7: '近7日',
|
|||
|
|
m1: '近1月',
|
|||
|
|
m3: '近3月',
|
|||
|
|
m6: '近6月',
|
|||
|
|
m12: '近1年',
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 机构类型
|
|||
|
|
const orgTypes = ['bank', 'nbank']
|
|||
|
|
|
|||
|
|
// 初始化结果数组
|
|||
|
|
const result = {
|
|||
|
|
totalApplyCount: [],
|
|||
|
|
totalOrgCount: [],
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 遍历每个时间维度
|
|||
|
|
for (const timeKey of Object.keys(timeDimensions)) {
|
|||
|
|
let totalApplyCount = 0 // 每个时间维度的总申请次数
|
|||
|
|
let totalOrgCount = 0 // 每个时间维度的总机构数
|
|||
|
|
|
|||
|
|
// 遍历每种机构类型并累加
|
|||
|
|
orgTypes.forEach((orgType) => {
|
|||
|
|
// 构造参数名
|
|||
|
|
const applyCountKey = `als_${timeKey}_id_${orgType}_allnum`
|
|||
|
|
const orgCountKey = `als_${timeKey}_id_${orgType}_orgnum`
|
|||
|
|
// 检查 data 中是否存在此参数,如果不存在则跳过
|
|||
|
|
if (data[applyCountKey] !== undefined && data[orgCountKey] !== undefined) {
|
|||
|
|
// 累加数值(如果值为 undefined 或 null 则转换为 0)
|
|||
|
|
totalApplyCount += Number(data[applyCountKey] || 0)
|
|||
|
|
totalOrgCount += Number(data[orgCountKey] || 0)
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
// 将每个时间维度的总申请次数和总机构数添加到结果数组中
|
|||
|
|
result.totalApplyCount.push(totalApplyCount)
|
|||
|
|
result.totalOrgCount.push(totalOrgCount)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return result
|
|||
|
|
}
|
|||
|
|
function typeTotalStats(data) {
|
|||
|
|
// 时间维度映射
|
|||
|
|
const timeDimensions = {
|
|||
|
|
d7: '近7日',
|
|||
|
|
m1: '近1月',
|
|||
|
|
m3: '近3月',
|
|||
|
|
m6: '近6月',
|
|||
|
|
m12: '近1年',
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 定义机构类型和对应的映射表
|
|||
|
|
const orgMappings = {
|
|||
|
|
bank: '银行借贷',
|
|||
|
|
mc: '小额贷款',
|
|||
|
|
cf: '消费分期',
|
|||
|
|
ca: '借款分期',
|
|||
|
|
rel: '信用卡',
|
|||
|
|
af: '汽车金融',
|
|||
|
|
other: '其他',
|
|||
|
|
}
|
|||
|
|
const tableGroup = {
|
|||
|
|
bank: [
|
|||
|
|
{ code: 'bank', name: '银行机构' },
|
|||
|
|
],
|
|||
|
|
mc: [
|
|||
|
|
{ code: 'nbank_mc', name: '小贷机构' },
|
|||
|
|
// { code: 'nbank_nsloan', name: '持牌网络小贷' },
|
|||
|
|
// { code: 'nbank_sloan', name: '持牌小贷机构' },
|
|||
|
|
// { code: 'pdl', name: '线上小额现金贷' },
|
|||
|
|
],
|
|||
|
|
cf: [
|
|||
|
|
{ code: 'nbank_cf', name: '消费类分期机构' },
|
|||
|
|
// { code: 'coon', name: '线上消费分期' },
|
|||
|
|
// { code: 'cooff', name: '线下消费分期' },
|
|||
|
|
],
|
|||
|
|
ca: [
|
|||
|
|
{ code: 'nbank_ca', name: '现金类分期机构' },
|
|||
|
|
// { code: 'caon', name: '线上现金分期' },
|
|||
|
|
// { code: 'caoff', name: '线下现金分期' },
|
|||
|
|
{ code: 'nbank_com', name: '代偿类分期机构' },
|
|||
|
|
],
|
|||
|
|
rel: [
|
|||
|
|
{ code: 'rel', name: '信用卡(类信用卡)' },
|
|||
|
|
],
|
|||
|
|
af: [
|
|||
|
|
{ code: 'af', name: '汽车金融' },
|
|||
|
|
// { code: 'nbank_autofin', name: '持牌汽车金融机构' },
|
|||
|
|
],
|
|||
|
|
other: [
|
|||
|
|
{ code: 'nbank_p2p', name: '改制机构' },
|
|||
|
|
{ code: 'nbank_cons', name: '持牌消费金融机构' },
|
|||
|
|
{ code: 'nbank_finlea', name: '持牌融资租赁机构' },
|
|||
|
|
{ code: 'nbank_oth', name: '申请其他' },
|
|||
|
|
{ code: 'nbank_else', name: '其他申请' },
|
|||
|
|
// { code: 'oth', name: '申请其他' },
|
|||
|
|
// { code: 'else', name: '其他申请' },
|
|||
|
|
],
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 初始化结果数组
|
|||
|
|
const result = []
|
|||
|
|
|
|||
|
|
// 遍历每个时间维度
|
|||
|
|
for (const timeKey of Object.keys(timeDimensions)) {
|
|||
|
|
const tableDataEntry = []
|
|||
|
|
|
|||
|
|
// 遍历每种机构类型并累加
|
|||
|
|
Object.keys(orgMappings).forEach((groupOrgType) => {
|
|||
|
|
const orgTypeArray = tableGroup[groupOrgType]
|
|||
|
|
|
|||
|
|
let totalApplyCount = 0
|
|||
|
|
let totalOrgCount = 0
|
|||
|
|
for (const i of orgTypeArray) {
|
|||
|
|
const applyCountKey = `als_${timeKey}_id_${i.code}_allnum`
|
|||
|
|
const orgCountKey = `als_${timeKey}_id_${i.code}_orgnum`
|
|||
|
|
totalApplyCount = totalApplyCount + Number(data[applyCountKey] || 0)
|
|||
|
|
totalOrgCount = totalOrgCount + Number(data[orgCountKey] || 0)
|
|||
|
|
}
|
|||
|
|
// 添加到 tableData
|
|||
|
|
tableDataEntry.push({
|
|||
|
|
label: orgMappings[groupOrgType],
|
|||
|
|
name: groupOrgType,
|
|||
|
|
totalApplyCount,
|
|||
|
|
totalOrgCount,
|
|||
|
|
})
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
result.push(tableDataEntry)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return result
|
|||
|
|
}
|
|||
|
|
function dateTotalStats(data) {
|
|||
|
|
// 时间维度映射
|
|||
|
|
const timeDimensions = {
|
|||
|
|
d7: '近7日',
|
|||
|
|
m1: '近1月',
|
|||
|
|
m3: '近3月',
|
|||
|
|
m6: '近6月',
|
|||
|
|
m12: '近1年',
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 定义机构类型和对应的映射表
|
|||
|
|
const orgMappings = {
|
|||
|
|
week: '周末',
|
|||
|
|
night: '夜间',
|
|||
|
|
}
|
|||
|
|
const tableGroup = {
|
|||
|
|
week: [
|
|||
|
|
{ code: 'bank_week', name: '周末银行' },
|
|||
|
|
{ code: 'nbank_week', name: '周末非银' },
|
|||
|
|
],
|
|||
|
|
night: [
|
|||
|
|
{ code: 'bank_night', name: '夜间银行' },
|
|||
|
|
{ code: 'nbank_night', name: '夜间非银' },
|
|||
|
|
],
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 初始化结果数组
|
|||
|
|
const result = []
|
|||
|
|
|
|||
|
|
// 遍历每个时间维度
|
|||
|
|
for (const timeKey of Object.keys(timeDimensions)) {
|
|||
|
|
const tableDataEntry = []
|
|||
|
|
|
|||
|
|
// 遍历每种机构类型并累加
|
|||
|
|
Object.keys(orgMappings).forEach((groupOrgType) => {
|
|||
|
|
const orgTypeArray = tableGroup[groupOrgType]
|
|||
|
|
|
|||
|
|
let totalApplyCount = 0
|
|||
|
|
let totalOrgCount = 0
|
|||
|
|
for (const i of orgTypeArray) {
|
|||
|
|
const applyCountKey = `als_${timeKey}_id_${i.code}_allnum`
|
|||
|
|
const orgCountKey = `als_${timeKey}_id_${i.code}_orgnum`
|
|||
|
|
totalApplyCount = totalApplyCount + Number(data[applyCountKey] || 0)
|
|||
|
|
totalOrgCount = totalOrgCount + Number(data[orgCountKey] || 0)
|
|||
|
|
}
|
|||
|
|
// 添加到 tableData
|
|||
|
|
tableDataEntry.push({
|
|||
|
|
label: orgMappings[groupOrgType],
|
|||
|
|
name: groupOrgType,
|
|||
|
|
totalApplyCount,
|
|||
|
|
totalOrgCount,
|
|||
|
|
})
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
result.push(tableDataEntry)
|
|||
|
|
}
|
|||
|
|
console.log('date result', result)
|
|||
|
|
return result
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<template>
|
|||
|
|
<div class="card">
|
|||
|
|
<div class="flex flex-col gap-y-4">
|
|||
|
|
<!-- 申请次数 -->
|
|||
|
|
<LTitle title="申请次数" type="blue-green" />
|
|||
|
|
<QiunDataCharts
|
|||
|
|
type="column"
|
|||
|
|
:opts="opts"
|
|||
|
|
:chart-data="chartData"
|
|||
|
|
/>
|
|||
|
|
|
|||
|
|
<!-- 银行类别申请记录 -->
|
|||
|
|
<LTitle title="申请类别" type="blue-green" />
|
|||
|
|
<LButtonGroup v-model="selectedOption" :options="options" />
|
|||
|
|
<LTable :data="tableData[selectedOption]" type="blue-green">
|
|||
|
|
<template #header>
|
|||
|
|
<th class="border px-4 py-2">
|
|||
|
|
借贷类别
|
|||
|
|
</th>
|
|||
|
|
<th class="border px-4 py-2">
|
|||
|
|
申请次数
|
|||
|
|
</th>
|
|||
|
|
<th class="border px-4 py-2">
|
|||
|
|
申请的机构数
|
|||
|
|
</th>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<template #default="{ row }">
|
|||
|
|
<td class="border px-4 py-2">
|
|||
|
|
{{ row.label }}
|
|||
|
|
</td>
|
|||
|
|
<td class="border px-4 py-2">
|
|||
|
|
{{ row.totalApplyCount }}
|
|||
|
|
</td>
|
|||
|
|
<td class="border px-4 py-2">
|
|||
|
|
{{ row.totalOrgCount }}
|
|||
|
|
</td>
|
|||
|
|
</template>
|
|||
|
|
</LTable>
|
|||
|
|
|
|||
|
|
<!-- 特殊时段申请记录 -->
|
|||
|
|
<LTitle title="特殊时段申请记录" type="blue-green" />
|
|||
|
|
<LButtonGroup v-model="dateSelectedOption" :options="dateOptions" />
|
|||
|
|
<LTable :data="dateTableData[dateSelectedOption]" type="blue-green">
|
|||
|
|
<!-- 表头 -->
|
|||
|
|
<template #header>
|
|||
|
|
<th class="border px-4 py-2">
|
|||
|
|
时段
|
|||
|
|
</th>
|
|||
|
|
<th class="border px-4 py-2">
|
|||
|
|
申请次数
|
|||
|
|
</th>
|
|||
|
|
<th class="border px-4 py-2">
|
|||
|
|
申请的机构数
|
|||
|
|
</th>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<!-- 渲染表格内容 -->
|
|||
|
|
<template #default="{ row }">
|
|||
|
|
<td class="border px-4 py-2">
|
|||
|
|
{{ row.label }}
|
|||
|
|
</td>
|
|||
|
|
<td class="border px-4 py-2">
|
|||
|
|
{{ row.totalApplyCount }}
|
|||
|
|
</td>
|
|||
|
|
<td class="border px-4 py-2">
|
|||
|
|
{{ row.totalOrgCount }}
|
|||
|
|
</td>
|
|||
|
|
</template>
|
|||
|
|
</LTable>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<style lang="scss" scoped>
|
|||
|
|
|
|||
|
|
</style>
|