Files
tyc-webview/src/ui/CBankLoanBehavior.vue
2025-12-25 14:49:46 +08:00

927 lines
34 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.

<script setup>
import * as echarts from "echarts"; // 引入 ECharts
import LTable from "@/components/LTable.vue";
import LTitle from "@/components/LTitle.vue";
import { ref, onMounted, watch, computed } from "vue";
const props = defineProps({
data: {
type: Object,
required: true,
},
mode: {
type: String,
default: "idOnly", // 'full' 或 'idOnly'
validator: (value) => ["full", "idOnly"].includes(value),
},
});
const { data, mode } = props;
// 数据类型切换
const dataType = ref("id"); // 'id' 或 'cell'
// 监听mode变化如果是idOnly模式强制selectedDataSource为"id"
watch(
() => props.mode,
(newMode) => {
if (newMode === "idOnly") {
dataType.value = "id";
}
},
{ immediate: true }
);
// 图表实例
const borrowChartRef = ref(null);
const repayChartRef = ref(null);
const trendChartRef = ref(null);
const borrowChartInstance = ref(null);
const repayChartInstance = ref(null);
const trendChartInstance = ref(null);
// 表格数据
const borrowTable = ref([]);
const institutionTable = ref([]);
// 获取参考日期
const getReferenceDate = computed(() => {
const prefix = `tl_${dataType.value}`;
const dateStr = data[`${prefix}_eletail_lasttime`];
if (dateStr) {
// 将字符串转为日期对象
return new Date(dateStr);
}
// 如果没有日期信息,则使用当前日期
return new Date();
});
// 根据相对月份获取实际年月
function getActualMonthYear(monthsBack) {
const month = monthsBack.replace("m", "");
if (month === "12") {
return "近1年";
}
return `${month}`;
// const refDate = new Date(getReferenceDate.value);
// refDate.setMonth(refDate.getMonth() - monthsBack);
// const year = refDate.getFullYear();
// const month = refDate.getMonth() + 1; // JavaScript月份从0开始
// return `${year}年${month}月`;
}
function getActualMonthYearT(monthsBack) {
if (monthsBack === "t0") {
return "1年内";
}
return `${monthsBack.replace("t", "")}`;
}
// 金额转换函数
function getLevelAmount(level) {
const levelNum = Number(level) || 1;
const baseAmount = 3000;
return baseAmount * (levelNum - 1);
}
// 等级范围转换
function getLevelRange(level) {
const levelNum = Number(level) || 1;
const baseAmount = 3000;
const lowerLimit = baseAmount * (levelNum - 1);
const upperLimit = baseAmount * levelNum;
return `${lowerLimit}元 - ${upperLimit}`;
}
// 计算借贷金额数据(按月)
const monthlyBorrowData = computed(() => {
const months = ["m1", "m3", "m6", "m9", "m12"];
const prefix = `tl_${dataType.value}`;
return months
.map((month, index) => {
const borrowKey = `${prefix}_${month}_nbank_passlendamt`;
const borrowAmount = getLevelAmount(data[borrowKey]);
console.log(borrowKey, borrowAmount);
return {
month: getActualMonthYear(month),
amount: borrowAmount,
displayAmount: formatAmount(borrowAmount),
level: data[borrowKey] || "0",
levelRange: getLevelRange(data[borrowKey]),
};
})
.reverse();
});
// 计算应还金额数据(按月)
const monthlyRepayData = computed(() => {
const months = ["m1", "m3", "m6", "m9", "m12"];
const prefix = `tl_${dataType.value}`;
return months
.map((month, index) => {
const repayKey = `${prefix}_${month}_nbank_reamt`;
const repayAmount = getLevelAmount(data[repayKey]);
return {
month: getActualMonthYear(month),
amount: repayAmount,
displayAmount: formatAmount(repayAmount),
level: data[repayKey] || "0",
levelRange: getLevelRange(data[repayKey]),
};
})
.reverse();
});
// 计算机构数和借还差值(按月)
const monthlyInstitutionData = computed(() => {
const months = ["m1", "m3", "m6", "m9", "m12"];
const prefix = `tl_${dataType.value}`;
return months
.map((month, index) => {
const orgKey = `${prefix}_${month}_nbank_passorg`;
const numKey = `${prefix}_${month}_nbank_passnum`;
const borrowKey = `${prefix}_${month}_nbank_passlendamt`;
const repayKey = `${prefix}_${month}_nbank_reamt`;
const orgCount = Number(data[orgKey] || 0);
const loanCount = Number(data[numKey] || 0);
const borrowAmount = getLevelAmount(data[borrowKey]);
const repayAmount = getLevelAmount(data[repayKey]);
let ratio = 0;
if (borrowAmount > 0) {
ratio = ((repayAmount / borrowAmount) * 100).toFixed(2);
}
return {
month: getActualMonthYear(month),
orgCount,
loanCount,
borrowAmount: formatAmount(borrowAmount),
repayAmount: formatAmount(repayAmount),
ratio: `${ratio}%`,
};
})
.reverse();
});
// 计算近期借贷趋势数据3月、6月、9月、12月
const recentBorrowTrends = computed(() => {
const months = ["t0"];
const prefix = `tl_${dataType.value}`;
return months
.map((month, index) => {
const orgKey = `${prefix}_${month}_nbank_org`;
const numKey = `${prefix}_${month}_nbank_num`;
const borrowKey = `${prefix}_${month}_nbank_lendamt`;
const repayKey = `${prefix}_${month}_nbank_reamt`;
const orgCount = Number(data[orgKey] || 0);
const loanCount = Number(data[numKey] || 0);
const borrowAmount = getLevelAmount(data[borrowKey]);
const repayAmount = getLevelAmount(data[repayKey]);
let ratio = 0;
if (borrowAmount > 0) {
ratio = ((repayAmount / borrowAmount) * 100).toFixed(2);
}
return {
month: getActualMonthYearT(month),
orgCount,
loanCount,
borrowAmount: formatAmount(borrowAmount),
repayAmount: formatAmount(repayAmount),
ratio: `${ratio}%`,
};
})
.reverse();
});
// 获取最近一次借贷信息
const lastLoanInfo = computed(() => {
const prefix = `tl_${dataType.value}`;
return {
time: data[`${prefix}_eletail_lasttime`] || "--",
type: getLoanTypeDesc(data[`${prefix}_eletail_lasttype`]),
count: Number(data[`${prefix}_eletail_num`] || 0),
orgCount: Number(data[`${prefix}_eletail_org`] || 0),
};
});
// 获取借贷类型描述
function getLoanTypeDesc(type) {
const typeMap = {
a: "传统银行",
b: "网络零售银行",
c: "持牌网络小贷",
d: "持牌小贷",
e: "持牌消费金融",
f: "持牌融资租赁",
g: "持牌汽车金融",
h: "其他",
};
return typeMap[type] || "未知";
}
// 金额格式化
function formatAmount(amount) {
return amount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
// 借贷行为总结
const behaviorSummary = computed(() => {
const prefix = `tl_${dataType.value}`;
// 获取近一年数据
const yearData = recentBorrowTrends.value[0];
// 计算平均月申请次数
const avgMonthlyApplications = (yearData.loanCount / 12).toFixed(1);
// 计算平均月审批额度
const totalBorrowAmount = Number(yearData.borrowAmount.replace(/,/g, ""));
const avgMonthlyAmount = (totalBorrowAmount / 12).toFixed(0);
// 计算平均月应还金额
const totalRepayAmount = Number(yearData.repayAmount.replace(/,/g, ""));
const avgMonthlyRepay = (totalRepayAmount / 12).toFixed(0);
// 计算还款比例
const repayRatio =
totalBorrowAmount > 0
? ((totalRepayAmount / totalBorrowAmount) * 100).toFixed(1)
: 0;
// 风险评估
let riskLevel = "低";
let riskDesc = "借贷行为健康,借贷金额合理";
// 基于机构数评估
if (yearData.orgCount > 5) {
riskLevel = "高";
riskDesc = "多头借贷风险较高,借贷机构过多";
} else if (yearData.orgCount > 3) {
riskLevel = "中";
riskDesc = "存在多头借贷风险,借贷机构较多";
}
// 基于月均申请次数评估
if (avgMonthlyApplications > 3) {
riskLevel = riskLevel === "低" ? "中" : "高";
riskDesc += ",月均申请次数较多";
}
// 基于还款比例评估
if (repayRatio < 50) {
riskLevel = riskLevel === "低" ? "中" : "高";
riskDesc += ",还款比例较低";
}
return {
totalApplications: yearData.loanCount,
totalOrgs: yearData.orgCount,
totalAmount: formatAmount(totalBorrowAmount),
avgMonthlyApplications,
avgMonthlyAmount: formatAmount(avgMonthlyAmount),
avgMonthlyRepay: formatAmount(avgMonthlyRepay),
repayRatio: `${repayRatio}%`,
riskLevel,
riskDesc,
};
});
// 绘制借贷金额图表
function drawBorrowChart() {
if (!borrowChartRef.value) return;
if (!borrowChartInstance.value) {
borrowChartInstance.value = echarts.init(borrowChartRef.value);
}
const chartData = monthlyBorrowData.value;
const option = {
title: {
text: "月度审批额度(元)",
left: "center",
textStyle: {
fontWeight: "bold",
fontSize: 16,
},
},
tooltip: {
trigger: "axis",
formatter: function (params) {
const data = params[0].data;
return `${params[0].name}<br/>${params[0].seriesName}: ${data.displayAmount}<br/>等级: ${data.level} (${data.levelRange})`;
},
backgroundColor: "rgba(255, 255, 255, 0.8)",
borderColor: "#5470C6",
borderWidth: 1,
textStyle: {
color: "#333",
},
shadowBlur: 10,
shadowColor: "rgba(0, 0, 0, 0.2)",
},
grid: {
left: "5%",
right: "5%",
bottom: "0%",
containLabel: true,
},
xAxis: {
type: "category",
data: chartData.map((item) => item.month),
axisLabel: {
interval: 0,
rotate: 45,
fontWeight: "bold",
margin: 15,
},
axisLine: {
lineStyle: {
color: "#999",
},
},
},
yAxis: {
type: "value",
name: "金额(元)",
nameTextStyle: {
fontWeight: "bold",
},
splitLine: {
lineStyle: {
type: "dashed",
opacity: 0.6,
},
},
},
series: [
{
name: "审批额度",
type: "bar",
data: chartData.map((item) => ({
value: item.amount,
displayAmount: item.displayAmount,
level: item.level,
levelRange: item.levelRange,
})),
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#83bff6" },
{ offset: 0.5, color: "#5470C6" },
{ offset: 1, color: "#4662a4" },
]),
borderRadius: [5, 5, 0, 0],
},
emphasis: {
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#5470C6" },
{ offset: 0.7, color: "#4662a4" },
{ offset: 1, color: "#3c5390" },
]),
},
},
barWidth: "60%",
showBackground: true,
backgroundStyle: {
color: "rgba(180, 180, 180, 0.1)",
},
},
],
animation: true,
};
borrowChartInstance.value.setOption(option);
}
// 绘制应还金额图表
function drawRepayChart() {
if (!repayChartRef.value) return;
if (!repayChartInstance.value) {
repayChartInstance.value = echarts.init(repayChartRef.value);
}
const chartData = monthlyRepayData.value;
const option = {
title: {
text: "月度应还金额(元)",
left: "center",
textStyle: {
fontWeight: "bold",
fontSize: 16,
},
},
tooltip: {
trigger: "axis",
formatter: function (params) {
const data = params[0].data;
return `${params[0].name}<br/>${params[0].seriesName}: ${data.displayAmount}<br/>等级: ${data.level} (${data.levelRange})`;
},
backgroundColor: "rgba(255, 255, 255, 0.8)",
borderColor: "#91CC75",
borderWidth: 1,
textStyle: {
color: "#333",
},
shadowBlur: 10,
shadowColor: "rgba(0, 0, 0, 0.2)",
},
grid: {
left: "5%",
right: "5%",
bottom: "15%",
containLabel: true,
},
xAxis: {
type: "category",
data: chartData.map((item) => item.month),
axisLabel: {
interval: 0,
rotate: 45,
fontWeight: "bold",
margin: 15,
},
axisLine: {
lineStyle: {
color: "#999",
},
},
},
yAxis: {
type: "value",
name: "金额(元)",
nameTextStyle: {
fontWeight: "bold",
},
splitLine: {
lineStyle: {
type: "dashed",
opacity: 0.6,
},
},
},
series: [
{
name: "应还金额",
type: "bar",
data: chartData.map((item) => ({
value: item.amount,
displayAmount: item.displayAmount,
level: item.level,
levelRange: item.levelRange,
})),
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#b8e986" },
{ offset: 0.5, color: "#91CC75" },
{ offset: 1, color: "#7cb362" },
]),
borderRadius: [5, 5, 0, 0],
},
emphasis: {
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#91CC75" },
{ offset: 0.7, color: "#7cb362" },
{ offset: 1, color: "#6a9c53" },
]),
},
},
barWidth: "60%",
showBackground: true,
backgroundStyle: {
color: "rgba(180, 180, 180, 0.1)",
},
},
],
animation: true,
};
repayChartInstance.value.setOption(option);
}
// 绘制借贷应还趋势对比图
function drawTrendChart() {
if (!trendChartRef.value) return;
if (!trendChartInstance.value) {
trendChartInstance.value = echarts.init(trendChartRef.value);
}
const borrowData = monthlyBorrowData.value;
const repayData = monthlyRepayData.value;
const option = {
title: {
text: "审批额度与应还金额趋势对比",
left: "center",
textStyle: {
fontWeight: "bold",
fontSize: 16,
},
},
tooltip: {
trigger: "axis",
backgroundColor: "rgba(255, 255, 255, 0.8)",
borderColor: "#ccc",
borderWidth: 1,
textStyle: {
color: "#333",
},
shadowBlur: 10,
shadowColor: "rgba(0, 0, 0, 0.2)",
},
legend: {
data: ["审批额度", "应还金额"],
top: 30,
textStyle: {
fontWeight: "bold",
},
},
grid: {
left: "5%",
right: "5%",
bottom: "15%",
containLabel: true,
},
xAxis: {
type: "category",
data: borrowData.map((item) => item.month),
axisLabel: {
interval: 0,
rotate: 45,
fontWeight: "bold",
margin: 15,
},
axisLine: {
lineStyle: {
color: "#999",
},
},
},
yAxis: {
type: "value",
name: "金额(元)",
nameTextStyle: {
fontWeight: "bold",
},
splitLine: {
lineStyle: {
type: "dashed",
opacity: 0.6,
},
},
},
series: [
{
name: "审批额度",
type: "line",
data: borrowData.map((item) => item.amount),
smooth: true,
symbol: "emptyCircle",
symbolSize: 8,
lineStyle: {
width: 3,
shadowColor: "rgba(0, 0, 0, 0.3)",
shadowBlur: 10,
shadowOffsetY: 8,
},
itemStyle: {
color: "#5470C6",
borderWidth: 2,
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "rgba(84, 112, 198, 0.5)" },
{ offset: 1, color: "rgba(84, 112, 198, 0.1)" },
]),
},
},
{
name: "应还金额",
type: "line",
data: repayData.map((item) => item.amount),
smooth: true,
symbol: "emptyCircle",
symbolSize: 8,
lineStyle: {
width: 3,
shadowColor: "rgba(0, 0, 0, 0.3)",
shadowBlur: 10,
shadowOffsetY: 8,
},
itemStyle: {
color: "#91CC75",
borderWidth: 2,
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "rgba(145, 204, 117, 0.5)" },
{ offset: 1, color: "rgba(145, 204, 117, 0.1)" },
]),
},
},
],
animation: true,
};
trendChartInstance.value.setOption(option);
}
// 监听数据类型变化
watch(dataType, () => {
drawBorrowChart();
drawRepayChart();
drawTrendChart();
});
// 初始化所有图表
function initCharts() {
drawBorrowChart();
drawRepayChart();
drawTrendChart();
}
// 窗口大小变化时重绘图表
function handleResize() {
if (borrowChartInstance.value) borrowChartInstance.value.resize();
if (repayChartInstance.value) repayChartInstance.value.resize();
if (trendChartInstance.value) trendChartInstance.value.resize();
}
onMounted(() => {
initCharts();
window.addEventListener("resize", handleResize);
});
onUnmounted(() => {
window.removeEventListener("resize", handleResize);
});
</script>
<template>
<div class="card">
<div class="flex flex-col gap-y-4">
<!-- 数据类型切换 -->
<div class="p-6 bg-white rounded-lg shadow-sm border border-gray-100 relative overflow-hidden mb-4">
<!-- 背景装饰元素 -->
<div class="absolute top-0 right-0 w-32 h-32 bg-blue-50 rounded-full -mr-8 -mt-8 opacity-60"></div>
<div class="absolute bottom-0 left-0 w-20 h-20 bg-green-50 rounded-full -ml-10 -mb-10 opacity-50"></div>
<div class="flex flex-col md:flex-row justify-between items-start md:items-center gap-4 relative z-10">
<div class="space-y-2">
<h2 class="text-xl font-semibold text-gray-800 flex items-center">
借贷行为分析报告
</h2>
<p class="text-sm text-gray-600 ml-6">
本报告统计审批额度与应还情况帮助评估信贷风险
</p>
</div>
<div v-if="mode === 'full'" class="flex flex-wrap gap-6 w-full md:w-auto">
<div class="flex-1 md:flex-none flex rounded-md shadow-sm relative">
<button type="button"
class="flex-1 py-2 px-4 text-sm font-medium rounded-l-md border transition-all duration-200 flex items-center"
:class="[
dataType === 'id'
? 'bg-gradient-to-r from-blue-500 to-blue-600 text-white border-blue-500 shadow-md'
: 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50',
]" @click="dataType = 'id'">
<svg v-if="dataType === 'id'" class="w-4 h-4 mr-1" fill="none" stroke="currentColor"
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<svg v-else class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M10 6H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V8a2 2 0 00-2-2h-5m-4 0V5a2 2 0 114 0v1m-4 0a2 2 0 104 0m-5 8a2 2 0 100-4 2 2 0 000 4zm0 0c1.306 0 2.417.835 2.83 2M9 14a3.001 3.001 0 00-2.83 2M15 11h3m-3 4h2">
</path>
</svg>
身份证数据
</button>
<button type="button"
class="flex-1 py-2 px-4 text-sm font-medium rounded-r-md border transition-all duration-200 flex items-center"
:class="[
dataType === 'cell'
? 'bg-gradient-to-r from-green-500 to-green-600 text-white border-green-500 shadow-md'
: 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50',
]" @click="dataType = 'cell'">
<svg v-if="dataType === 'cell'" class="w-4 h-4 mr-1" fill="none" stroke="currentColor"
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<svg v-else class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z">
</path>
</svg>
手机号数据
</button>
</div>
</div>
</div>
<!-- 数据类型说明 -->
<div v-if="mode === 'full'" class="mt-4 bg-blue-50 p-3 rounded-lg text-xs text-gray-700">
<p class="font-medium text-blue-800 mb-1">数据类型说明</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-2">
<div class="flex items-start">
<span class="inline-block w-2 h-2 mt-1 mr-2 rounded-full flex-shrink-0 bg-blue-500"></span>
<span><strong>身份证数据</strong>通过身份证号码匹配获取的借贷记录反映与身份证关联的所有借贷行为</span>
</div>
<div class="flex items-start">
<span class="inline-block w-2 h-2 mt-1 mr-2 rounded-full flex-shrink-0 bg-green-500"></span>
<span><strong>手机号数据</strong>通过手机号码匹配获取的借贷记录反映与手机号关联的所有借贷行为</span>
</div>
</div>
</div>
</div>
<!-- 借贷金额图表 -->
<LTitle title="近期审批额度" type="blue-green" />
<div ref="borrowChartRef" class="chart-container"></div>
<!-- 应还金额图表 -->
<!--<LTitle title="月度应还金额" type="blue-green" />
<div ref="repayChartRef" class="chart-container"></div> -->
<!-- 借贷应还趋势对比 -->
<!--<LTitle title="审批额度与应还金额趋势对比" type="blue-green" />
<div ref="trendChartRef" class="chart-container"></div> -->
<!-- 借贷机构数和借还差值比例表格 -->
<LTitle title="近期通过借贷审批情况" type="blue-green" />
<div class="overflow-x-auto">
<LTable :data="monthlyInstitutionData" type="blue-green">
<template #header>
<th class="border px-1 py-2 text-xs min-w-[25%]">
时间
</th>
<th class="border px-1 py-2 text-xs min-w-[15%]">
借贷机构数
</th>
<th class="border px-1 py-2 text-xs min-w-[15%]">
借贷次数
</th>
<th class="border px-1 py-2 text-xs min-w-[15%]">
审批额度
</th>
<!-- <th class="border px-1 py-2 text-xs min-w-[15%]">
应还金额
</th>
<th class="border px-1 py-2 text-xs min-w-[15%]">
应还比例
</th> -->
</template>
<template #default="{ row }">
<td class="border px-1 py-2 text-xs">
{{ row.month }}
</td>
<td class="border px-1 py-2 text-xs text-center">
{{ row.orgCount }}
</td>
<td class="border px-1 py-2 text-xs text-center">
{{ row.loanCount }}
</td>
<td class="border px-1 py-2 text-xs text-center">
{{ row.borrowAmount }}
</td>
<!-- <td class="border px-1 py-2 text-xs text-center">
{{ row.repayAmount }}
</td>
<td class="border px-1 py-2 text-xs text-center">
{{ row.ratio }}
</td> -->
</template>
</LTable>
</div>
<!-- 近期借贷趋势表格 -->
<LTitle title="近1年借贷情况" type="blue-green" />
<div class="overflow-x-auto">
<LTable :data="recentBorrowTrends" type="blue-green">
<template #header>
<th class="border px-1 py-2 text-xs min-w-[25%]">
时间
</th>
<th class="border px-1 py-2 text-xs min-w-[15%]">
借贷机构数
</th>
<th class="border px-1 py-2 text-xs min-w-[15%]">
借贷次数
</th>
<th class="border px-1 py-2 text-xs min-w-[15%]">
审批额度
</th>
<th class="border px-1 py-2 text-xs min-w-[15%]">
应还金额
</th>
<th class="border px-1 py-2 text-xs min-w-[15%]">
审批与应还比例
</th>
</template>
<template #default="{ row }">
<td class="border px-1 py-2 text-xs">
{{ row.month }}
</td>
<td class="border px-1 py-2 text-xs text-center">
{{ row.orgCount }}
</td>
<td class="border px-1 py-2 text-xs text-center">
{{ row.loanCount }}
</td>
<td class="border px-1 py-2 text-xs text-center">
{{ row.borrowAmount }}
</td>
<td class="border px-1 py-2 text-xs text-center">
{{ row.repayAmount }}
</td>
<td class="border px-1 py-2 text-xs text-center">
{{ row.ratio }}
</td>
</template>
</LTable>
</div>
<!-- 借贷行为总结 -->
<LTitle title="借贷行为总结分析" type="blue-green" />
<div class="summary-container bg-blue-50 p-4 rounded-md">
<div class="text-xs text-gray-500 mb-2">
数据时间范围: 近1年
</div>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-4">
<div class="info-card p-3 bg-white rounded shadow-sm">
<div class="text-sm text-gray-500">总申请次数</div>
<div class="text-lg font-semibold">
{{ behaviorSummary.totalApplications }}
</div>
</div>
<div class="info-card p-3 bg-white rounded shadow-sm">
<div class="text-sm text-gray-500">借贷机构数</div>
<div class="text-lg font-semibold">
{{ behaviorSummary.totalOrgs }}
</div>
</div>
<div class="info-card p-3 bg-white rounded shadow-sm">
<div class="text-sm text-gray-500">总审批额度</div>
<div class="text-lg font-semibold">
{{ behaviorSummary.totalAmount }}
</div>
</div>
<div class="info-card p-3 bg-white rounded shadow-sm">
<div class="text-sm text-gray-500">月均申请次数</div>
<div class="text-lg font-semibold">
{{ behaviorSummary.avgMonthlyApplications }}
</div>
</div>
</div>
<div class="risk-assessment p-4 bg-white rounded-md">
<div class="text-lg font-bold mb-2">
风险评估:
<span :class="{
'text-red-500':
behaviorSummary.riskLevel === '高',
'text-yellow-500':
behaviorSummary.riskLevel === '中',
'text-green-500':
behaviorSummary.riskLevel === '低',
}">{{ behaviorSummary.riskLevel }}风险</span>
</div>
<div class="text-gray-700">
<p>
· 月均审批额度:
{{ behaviorSummary.avgMonthlyAmount }}
</p>
<p>
· 月均应还金额:
{{ behaviorSummary.avgMonthlyRepay }}
</p>
<p>· 还款比例: {{ behaviorSummary.repayRatio }}</p>
<p>· {{ behaviorSummary.riskDesc }}</p>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.chart-container {
width: 100%;
height: 300px;
margin-bottom: 20px;
}
</style>