1
This commit is contained in:
@@ -31,6 +31,10 @@ const featureMap = {
|
||||
name: '司法涉诉',
|
||||
component: defineAsyncComponent(() => import('@/ui/CLawsuit.vue')),
|
||||
},
|
||||
G22SC01: {
|
||||
name: '司法涉诉',
|
||||
component: defineAsyncComponent(() => import('@/ui/CLawsuitPP.vue')),
|
||||
},
|
||||
G05HZ01: {
|
||||
name: '股东人企关系',
|
||||
component: defineAsyncComponent(() => import('@/ui/CRelatedEnterprises.vue')),
|
||||
@@ -115,6 +119,273 @@ onMounted(() => {
|
||||
getReport()
|
||||
});
|
||||
|
||||
// 计算综合评分的函数
|
||||
const calculateScore = (reportData) => {
|
||||
// 从0分开始
|
||||
let score = 0;
|
||||
// 最高分为90分
|
||||
const maxScore = 90;
|
||||
|
||||
// 定义各接口的相对权重比例(而非固定分值)
|
||||
const relativeWeights = {
|
||||
// 关键风险指标(高优先级)
|
||||
'G34BJ03': 250, // 不良记录
|
||||
'G26BJ05': 100, // 违约异常
|
||||
'G22SC01': 400, // 司法涉诉
|
||||
'G35SC01': 20, // 司法涉诉(次要)
|
||||
'Q23SC01': 50, // 企业涉诉
|
||||
'FIN019': 100, // 银行卡黑名单
|
||||
|
||||
// 高风险指标(中优先级)
|
||||
'G27BJ05': 40, // 借贷申请记录
|
||||
'G28BJ05': 40, // 借贷行为记录
|
||||
'G03HZ01': 70, // 手机号码风险
|
||||
|
||||
// 中风险指标(低优先级)
|
||||
'G19BJ02': 50, // 手机二次卡
|
||||
'G02BJ02': 50, // 手机在网时长
|
||||
'G05HZ01': 50, // 人企关系
|
||||
|
||||
// 验证指标(最低优先级)
|
||||
'G15BJ02': 25, // 手机三要素
|
||||
'G17BJ02': 25, // 手机号二要素
|
||||
'KZEYS': 25, // 身份证二要素
|
||||
'G20GZ01': 25 // 银行卡四要素核验
|
||||
};
|
||||
|
||||
// 找出当前报告中包含的接口
|
||||
const availableAPIs = reportData.map(item => item.data.apiID).filter(id => relativeWeights[id]);
|
||||
|
||||
// 如果没有可评分的接口,返回默认分数
|
||||
if (availableAPIs.length === 0) return 60; // 默认60分
|
||||
|
||||
// 计算当前报告中所有接口的相对权重总和
|
||||
let totalWeight = 0;
|
||||
availableAPIs.forEach(apiID => {
|
||||
totalWeight += relativeWeights[apiID];
|
||||
});
|
||||
|
||||
// 计算每个权重点对应的分数
|
||||
const pointValue = maxScore / totalWeight;
|
||||
|
||||
// 基于当前报告中的接口计算实际权重
|
||||
const actualWeights = {};
|
||||
availableAPIs.forEach(apiID => {
|
||||
// 将相对权重转换为实际分数权重
|
||||
actualWeights[apiID] = relativeWeights[apiID] * pointValue;
|
||||
});
|
||||
|
||||
// 遍历报告数据进行评分
|
||||
reportData.forEach(item => {
|
||||
const apiID = item.data.apiID;
|
||||
const data = item.data.data;
|
||||
|
||||
// 如果没有定义权重,跳过
|
||||
if (!actualWeights[apiID]) return;
|
||||
|
||||
// 根据不同的API ID计算分数(只有没有风险或风险低时加分)
|
||||
switch (apiID) {
|
||||
case 'G09SC02': // 婚姻状态
|
||||
// 不计入风险
|
||||
break;
|
||||
|
||||
case 'G27BJ05': // 借贷申请记录
|
||||
if (data) {
|
||||
// 检查所有字段是否都为0(没有风险)
|
||||
let noRisk = true;
|
||||
for (const key in data) {
|
||||
if (data[key] !== 0 && data[key] !== '0') {
|
||||
noRisk = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (noRisk || !Object.keys(data).length) {
|
||||
score += actualWeights[apiID];
|
||||
}
|
||||
} else {
|
||||
// 无数据视为无风险
|
||||
score += actualWeights[apiID];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'G28BJ05': // 借贷行为记录
|
||||
if (data) {
|
||||
// 检查所有字段是否都为0(没有风险)
|
||||
let noRisk = true;
|
||||
for (const key in data) {
|
||||
if (data[key] !== 0 && data[key] !== '0') {
|
||||
noRisk = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (noRisk || !Object.keys(data).length) {
|
||||
score += actualWeights[apiID];
|
||||
}
|
||||
} else {
|
||||
// 无数据视为无风险
|
||||
score += actualWeights[apiID];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'G26BJ05': // 违约异常
|
||||
if (data) {
|
||||
// 检查除特定字段外的其他字段是否都为0(没有风险)
|
||||
const excludeFields = ['swift_number', 'code', 'flag_specialList_c'];
|
||||
let noRisk = true;
|
||||
|
||||
for (const key in data) {
|
||||
if (!excludeFields.includes(key) && data[key] !== 0 && data[key] !== '0') {
|
||||
noRisk = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (noRisk || !Object.keys(data).length) {
|
||||
score += actualWeights[apiID];
|
||||
}
|
||||
} else {
|
||||
// 无数据视为无风险
|
||||
score += actualWeights[apiID];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'G34BJ03': // 不良记录
|
||||
if (data && data.risk_level) {
|
||||
// 根据风险等级加分
|
||||
switch (data.risk_level) {
|
||||
case 'A': // 无风险
|
||||
score += actualWeights[apiID];
|
||||
break;
|
||||
case 'F': // 低风险
|
||||
score += actualWeights[apiID] * 0.7;
|
||||
break;
|
||||
case 'C': // 中风险
|
||||
case 'D': // 中风险
|
||||
score += actualWeights[apiID] * 0.3;
|
||||
break;
|
||||
case 'B': // 高风险
|
||||
case 'E': // 高风险
|
||||
// 不加分
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// 无数据视为无风险
|
||||
score += actualWeights[apiID];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'G35SC01': // 司法涉诉
|
||||
case 'G22SC01': // 司法涉诉
|
||||
case 'Q23SC01': // 企业涉诉
|
||||
if (data) {
|
||||
let hasRisk = false;
|
||||
|
||||
// 检查各种涉诉信息 - 处理嵌套数据结构
|
||||
// entout是一个单元素数组,数组中第一个元素是JSON对象,对象中有entout属性
|
||||
if (data.entout && Array.isArray(data.entout) && data.entout.length > 0 &&
|
||||
data.entout[0] && data.entout[0].entout &&
|
||||
((Array.isArray(data.entout[0].entout) && data.entout[0].entout.length > 0) ||
|
||||
(typeof data.entout[0].entout === 'object' && Object.keys(data.entout[0].entout).length > 0))) {
|
||||
hasRisk = true;
|
||||
}
|
||||
|
||||
// 处理sxbzxr(失信被执行人)嵌套结构
|
||||
if (data.sxbzxr && Array.isArray(data.sxbzxr) && data.sxbzxr.length > 0 &&
|
||||
data.sxbzxr[0] && data.sxbzxr[0].sxbzxr &&
|
||||
((Array.isArray(data.sxbzxr[0].sxbzxr) && data.sxbzxr[0].sxbzxr.length > 0) ||
|
||||
(typeof data.sxbzxr[0].sxbzxr === 'object' && Object.keys(data.sxbzxr[0].sxbzxr).length > 0))) {
|
||||
hasRisk = true;
|
||||
}
|
||||
|
||||
// 处理xgbzxr(限制高消费被执行人)嵌套结构
|
||||
if (data.xgbzxr && Array.isArray(data.xgbzxr) && data.xgbzxr.length > 0 &&
|
||||
data.xgbzxr[0] && data.xgbzxr[0].xgbzxr &&
|
||||
((Array.isArray(data.xgbzxr[0].xgbzxr) && data.xgbzxr[0].xgbzxr.length > 0) ||
|
||||
(typeof data.xgbzxr[0].xgbzxr === 'object' && Object.keys(data.xgbzxr[0].xgbzxr).length > 0))) {
|
||||
hasRisk = true;
|
||||
}
|
||||
|
||||
if (!hasRisk) {
|
||||
score += actualWeights[apiID];
|
||||
}
|
||||
} else {
|
||||
// 无数据视为无风险
|
||||
score += actualWeights[apiID];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'G03HZ01': // 手机号码风险
|
||||
if (data && data.filterType) {
|
||||
// 根据filterType判断风险等级
|
||||
switch (data.filterType) {
|
||||
case '0': // 安全
|
||||
score += actualWeights[apiID];
|
||||
break;
|
||||
case '3': // 低危
|
||||
score += actualWeights[apiID] * 0.7;
|
||||
break;
|
||||
case '2': // 中危
|
||||
score += actualWeights[apiID] * 0.3;
|
||||
break;
|
||||
case '1': // 高危
|
||||
// 不加分
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// 无数据视为无风险
|
||||
score += actualWeights[apiID];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'G19BJ02': // 手机二次卡
|
||||
if (data && data.is_second_card === false) {
|
||||
score += actualWeights[apiID];
|
||||
} else if (!data) {
|
||||
// 无数据视为无风险
|
||||
score += actualWeights[apiID];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'G02BJ02': // 手机在网时长
|
||||
if (data && data.online_months >= 6) {
|
||||
score += actualWeights[apiID];
|
||||
} else if (!data) {
|
||||
// 无数据视为无风险
|
||||
score += actualWeights[apiID];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'G15BJ02': // 手机三要素
|
||||
case 'G17BJ02': // 手机号二要素
|
||||
case 'KZEYS': // 身份证二要素
|
||||
case 'G20GZ01': // 银行卡四要素核验
|
||||
if (data && data.is_consistent) {
|
||||
score += actualWeights[apiID];
|
||||
} else if (!data) {
|
||||
// 无数据视为无风险
|
||||
score += actualWeights[apiID];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'FIN019': // 银行卡黑名单
|
||||
if (data && data.is_blacklisted === false) {
|
||||
score += actualWeights[apiID];
|
||||
} else if (!data) {
|
||||
// 无数据视为无风险
|
||||
score += actualWeights[apiID];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// 未知接口类型不影响评分
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// 确保分数在0-90范围内并四舍五入
|
||||
return Math.max(0, Math.min(maxScore, Math.round(score)));
|
||||
};
|
||||
|
||||
const getReport = async () => {
|
||||
let queryUrl = ""
|
||||
if (orderNo.value) {
|
||||
@@ -137,6 +408,10 @@ const getReport = async () => {
|
||||
reportParams.value = data.value.data.query_params
|
||||
reportName.value = data.value.data.product_name
|
||||
reportDateTime.value = data.value.data.create_time
|
||||
|
||||
|
||||
// 计算综合评分
|
||||
reportScore.value = calculateScore(reportData.value);
|
||||
} else if (data.value.code === 200003) {
|
||||
isEmpty.value = true
|
||||
} else if (data.value.code === 200002) {
|
||||
@@ -207,6 +482,15 @@ const maskValue = computed(() => {
|
||||
<div class="flex flex-col gap-y-4 p-4">
|
||||
<LEmpty v-if="isEmpty" />
|
||||
<template v-if="!isEmpty && !isPending">
|
||||
<van-tab title="分析指数">
|
||||
|
||||
<div id="overdiv" class="title mb-4">分析指数</div>
|
||||
<div class="card mb-4">
|
||||
<div class="my-4">
|
||||
<GaugeChart :score="reportScore" />
|
||||
</div>
|
||||
</div>
|
||||
</van-tab>
|
||||
<van-tab title="基本信息">
|
||||
<div id="overdiv" class="title mb-4">基本信息</div>
|
||||
<div class="card">
|
||||
|
||||
Reference in New Issue
Block a user