This commit is contained in:
2026-04-30 21:07:16 +08:00
parent 69a81a927a
commit cb079f6da7
6 changed files with 20512 additions and 7 deletions

View File

@@ -814,7 +814,12 @@ const featureMap = {
component: defineAsyncComponent(() => import("@/ui/JRZQ3C9R/index.vue")), component: defineAsyncComponent(() => import("@/ui/JRZQ3C9R/index.vue")),
remark: '支付表现是指数基于近两年的查验记录、还款成功与失败表现以及余额不足情况,对用户支付与还款习惯进行量化评分,用于评估其支付稳定性与违约风险。' remark: '支付表现是指数基于近两年的查验记录、还款成功与失败表现以及余额不足情况,对用户支付与还款习惯进行量化评分,用于评估其支付稳定性与违约风险。'
}, },
// 学历信息
IVYZ4Y27: {
name: "学历信息",
component: defineAsyncComponent(() => import("@/ui/IVYZ4Y27/index.vue")),
remark: '学历信息展示专业能力相关的学习经历,包括院校名称、学习类型、专业方向、学习时间、学历等级及核心竞争力等级等字段。',
},
}; };
const maskValue = computed(() => { const maskValue = computed(() => {
@@ -923,6 +928,7 @@ const featureRiskLevels = {
'IVYZ9A2B': 4, // 学历信息 'IVYZ9A2B': 4, // 学历信息
'IVYZ3P9M': 4, // 学历信息查询(实时版) 'IVYZ3P9M': 4, // 学历信息查询(实时版)
'IVYZ0S0D': 10, // 劳动仲裁信息 'IVYZ0S0D': 10, // 劳动仲裁信息
'IVYZ4Y27': 3, // 学历信息
// 📊 复合报告类 - 按子模块动态计算 // 📊 复合报告类 - 按子模块动态计算
@@ -1129,7 +1135,8 @@ const showPublicSecurityRecord = import.meta.env.VITE_SHOW_PUBLIC_SECURITY_RECOR
<TitleBanner :id="item.data.apiID" class="mb-0 flex-1"> <TitleBanner :id="item.data.apiID" class="mb-0 flex-1">
{{ featureMap[item.data.apiID]?.name }} {{ featureMap[item.data.apiID]?.name }}
</TitleBanner> </TitleBanner>
<van-button v-if="!isShare && !isExample && isAgentOrder && !getFeatureStatus(item.data.apiID).isOfflined" <van-button
v-if="!isShare && !isExample && isAgentOrder && !getFeatureStatus(item.data.apiID).isOfflined"
size="small" type="default" :loading="getFeatureStatus(item.data.apiID).isSubmitting" size="small" type="default" :loading="getFeatureStatus(item.data.apiID).isSubmitting"
@click="handleOfflineClick(item.data.apiID, featureMap[item.data.apiID]?.name)"> @click="handleOfflineClick(item.data.apiID, featureMap[item.data.apiID]?.name)">
下架 下架
@@ -1188,16 +1195,16 @@ const showPublicSecurityRecord = import.meta.env.VITE_SHOW_PUBLIC_SECURITY_RECOR
</div> </div>
<!-- 下架确认弹窗付费场景 --> <!-- 下架确认弹窗付费场景 -->
<van-dialog v-model:show="showOfflineConfirmDialog" title="确认下架" <van-dialog v-model:show="showOfflineConfirmDialog" title="确认下架" show-cancel-button @confirm="confirmOffline">
show-cancel-button @confirm="confirmOffline">
<div class="p-4 text-gray-600"> <div class="p-4 text-gray-600">
确定要下架{{ currentOfflineFeature?.featureName || '该模块' }}需支付 ¥{{ currentOfflineFeature?.whitelistPrice?.toFixed(2) || '0.00' }} 确定要下架{{ currentOfflineFeature?.featureName || '该模块' }}需支付 ¥{{
currentOfflineFeature?.whitelistPrice?.toFixed(2) || '0.00' }}
</div> </div>
</van-dialog> </van-dialog>
<!-- 白名单下架支付弹窗 --> <!-- 白名单下架支付弹窗 -->
<Payment v-model="showWhitelistPayment" :data="whitelistPaymentData" <Payment v-model="showWhitelistPayment" :data="whitelistPaymentData" :id="whitelistPaymentId"
:id="whitelistPaymentId" :type="whitelistPaymentType" :return-url="getCurrentReportUrl()" /> :type="whitelistPaymentType" :return-url="getCurrentReportUrl()" />
</template> </template>

View File

@@ -0,0 +1,34 @@
[
{
"value": "A",
"label": "985院校"
},
{
"value": "B",
"label": "双一流"
},
{
"value": "C",
"label": "211院校"
},
{
"value": "D",
"label": "一本院校"
},
{
"value": "E",
"label": "二本院校"
},
{
"value": "F",
"label": "大专院校"
},
{
"value": "G",
"label": "成人本科"
},
{
"value": "H",
"label": "其他"
}
]

View File

@@ -0,0 +1,22 @@
[
{
"value": "9",
"label": "博士研究生"
},
{
"value": "8",
"label": "硕士研究生"
},
{
"value": "7",
"label": "本科"
},
{
"value": "6",
"label": "大专"
},
{
"value": "5",
"label": "其他"
}
]

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

282
src/ui/IVYZ4Y27/index.vue Normal file
View File

@@ -0,0 +1,282 @@
<script setup>
import { computed, onMounted } from 'vue';
import { useRiskNotifier } from '@/composables/useRiskNotifier';
import abilityCompetitive from './abilityCompetitive.json';
import abilityCompetitiveDegree from './abilityCompetitiveDegree.json';
import abilityName from './abilityName.json';
import abilityField from './abilityField.json';
const props = defineProps({
data: {
type: Object,
default: () => ({})
},
apiId: {
type: String,
default: '',
},
index: {
type: Number,
default: 0,
},
notifyRiskStatus: {
type: Function,
default: () => { },
},
});
// 导入图片图标
import rkpmIcon from '@/assets/images/report/rkpm.png';
import zymcIcon from '@/assets/images/report/zymc.png';
import xxxsIcon from '@/assets/images/report/xxxs.png';
import xxlxIcon from '@/assets/images/report/xxlx.png';
import bysjIcon from '@/assets/images/report/bysj.png';
import xlIcon from '@/assets/images/report/xl.png';
// 计算风险评分
const riskScore = computed(() => {
return 100;
});
// 使用 composable 通知父组件风险评分
useRiskNotifier(props, riskScore);
// 暴露给父组件
defineExpose({
riskScore
});
// 获取列表数据
const abilityList = computed(() => {
return props.data?.abilityInfo || [];
});
// 字典映射
const competitiveMap = {};
abilityCompetitive.forEach(item => {
competitiveMap[item.value] = item.label;
});
const competitiveDegreeMap = {};
abilityCompetitiveDegree.forEach(item => {
competitiveDegreeMap[item.value] = item.label;
});
const nameMap = {};
abilityName.forEach(item => {
nameMap[item.value] = item.label;
});
const fieldMap = {};
abilityField.forEach(item => {
fieldMap[item.value] = item.label;
});
// 翻译函数
const getCompetitiveLabel = (val) => competitiveMap[val] || val || '未知';
const getCompetitiveDegreeLabel = (val) => competitiveDegreeMap[val] || val || '未知';
const getNameLabel = (val) => nameMap[val] || val || '未知';
// 专业方向翻译C99999/B99999 等以 99999 结尾的表示未匹配到相关专业
const getFieldLabel = (val) => {
if (!val) return '未知';
if (val.endsWith('99999')) {
const prefix = val.charAt(0);
const prefixMap = { 'A': '硕士研究生/博士研究生', 'B': '本科', 'C': '专科' };
return `${prefixMap[prefix] || ''}(未匹配到相关专业)`;
}
return fieldMap[val] || val || '未知';
};
// 格式化日期 yyyy-MM-dd -> yyyy年MM月dd日
const formatDate = (dateStr) => {
if (!dateStr) return '未知';
const parts = dateStr.split('-');
if (parts.length === 3) {
return `${parts[0]}${parts[1]}${parts[2]}`;
}
if (parts.length === 2) {
return `${parts[0]}${parts[1]}`;
}
return dateStr;
};
// 获取核心竞争力等级对应的颜色样式
const getCompetitiveBadgeClass = (val) => {
const classMap = {
'A': 'bg-amber-500 text-white',
'B': 'bg-green-500 text-white',
'C': 'bg-blue-500 text-white',
'D': 'bg-indigo-500 text-white',
'E': 'bg-cyan-500 text-white',
'F': 'bg-gray-500 text-white',
'G': 'bg-orange-500 text-white',
'H': 'bg-gray-400 text-white',
};
return classMap[val] || 'bg-gray-400 text-white';
};
// 获取学历等级对应的颜色样式
const getDegreeBadgeClass = (val) => {
const classMap = {
'9': 'bg-purple-500 text-white',
'8': 'bg-blue-600 text-white',
'7': 'bg-blue-500 text-white',
'6': 'bg-cyan-600 text-white',
'5': 'bg-gray-500 text-white',
};
return classMap[val] || 'bg-gray-400 text-white';
};
// 判断是否有数据
const hasData = computed(() => {
return abilityList.value.length > 0;
});
</script>
<template>
<div v-if="hasData" class="card max-w-4xl mx-auto">
<!-- 头部区域 -->
<div class="mb-6">
<div class="flex items-center justify-between mb-4">
<div class="flex items-center gap-3">
<div class="w-12 h-12 flex items-center justify-center">
<img :src="xlIcon" alt="学历图标" class="w-12 h-12" />
</div>
<div>
<h2 class="text-2xl font-bold text-gray-900">学历信息</h2>
<p class="text-sm text-gray-500">Education Information</p>
</div>
</div>
<div class="text-sm text-gray-500">
{{ abilityList.length }} 条记录
</div>
</div>
</div>
<!-- 学历列表 -->
<div class="space-y-6">
<div v-for="(item, idx) in abilityList" :key="idx"
class="bg-white border border-gray-200 rounded-xl overflow-hidden hover:shadow-md transition-shadow">
<!-- 顶部学历等级与核心竞争力 -->
<div class="bg-gradient-to-r from-blue-50 to-indigo-50 px-5 py-4 border-b border-blue-100">
<div class="flex items-center justify-between flex-wrap gap-2">
<div class="flex items-center gap-3">
<div class="w-10 h-10 rounded-full bg-blue-500 flex items-center justify-center">
<span class="text-white text-lg font-bold">{{ idx + 1 }}</span>
</div>
<div>
<div class="flex items-center gap-2 flex-wrap">
<span v-if="item.abilityCompetitiveDegree"
:class="['inline-flex items-center px-3 py-1 rounded-full text-sm font-medium', getDegreeBadgeClass(item.abilityCompetitiveDegree)]">
{{ getCompetitiveDegreeLabel(item.abilityCompetitiveDegree) }}
</span>
<span v-if="item.abilityCompetitive"
:class="['inline-flex items-center px-3 py-1 rounded-full text-xs font-medium', getCompetitiveBadgeClass(item.abilityCompetitive)]">
{{ getCompetitiveLabel(item.abilityCompetitive) }}
</span>
</div>
</div>
</div>
</div>
</div>
<!-- 详细信息 -->
<div class="p-5">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<!-- 院校名称 -->
<div v-if="item.abilityName"
class="bg-gray-50 rounded-lg p-4 border border-gray-200 hover:border-blue-300 transition-colors">
<div class="flex items-start gap-3">
<div class="w-8 h-8 flex items-center justify-center flex-shrink-0 mt-1">
<img :src="xxlxIcon" alt="院校名称" class="w-8 h-8" />
</div>
<div class="flex-1">
<div class="text-sm text-gray-600 mb-1">院校名称</div>
<div class="text-base font-medium text-gray-900">{{ getNameLabel(item.abilityName)
}}</div>
</div>
</div>
</div>
<!-- 学习类型 -->
<div v-if="item.abilityType"
class="bg-gray-50 rounded-lg p-4 border border-gray-200 hover:border-blue-300 transition-colors">
<div class="flex items-start gap-3">
<div class="w-8 h-8 flex items-center justify-center flex-shrink-0 mt-1">
<img :src="xxxsIcon" alt="学习类型" class="w-8 h-8" />
</div>
<div class="flex-1">
<div class="text-sm text-gray-600 mb-1">学习类型</div>
<div class="text-base font-medium text-gray-900">{{ item.abilityType }}</div>
</div>
</div>
</div>
<!-- 专业方向 -->
<div v-if="item.abilityField"
class="bg-gray-50 rounded-lg p-4 border border-gray-200 hover:border-blue-300 transition-colors">
<div class="flex items-start gap-3">
<div class="w-8 h-8 flex items-center justify-center flex-shrink-0 mt-1">
<img :src="zymcIcon" alt="专业方向" class="w-8 h-8" />
</div>
<div class="flex-1">
<div class="text-sm text-gray-600 mb-1">专业方向</div>
<div class="text-base font-medium text-gray-900">{{ getFieldLabel(item.abilityField)
}}</div>
</div>
</div>
</div>
<!-- 学习时间 -->
<div v-if="item.abilityStartDate || item.abilityEndDate"
class="bg-gray-50 rounded-lg p-4 border border-gray-200 hover:border-blue-300 transition-colors">
<div class="flex items-start gap-3">
<div class="w-8 h-8 flex items-center justify-center flex-shrink-0 mt-1">
<img :src="bysjIcon" alt="学习时间" class="w-8 h-8" />
</div>
<div class="flex-1">
<div class="text-sm text-gray-600 mb-1">学习时间</div>
<div class="text-base font-medium text-gray-900">
{{ formatDate(item.abilityStartDate) }} ~ {{ formatDate(item.abilityEndDate) }}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 无数据状态 -->
<div v-else class="card max-w-2xl mx-auto">
<div class="flex flex-col items-center py-12 text-center">
<div class="w-20 h-20 flex items-center justify-center mb-4">
<img :src="xlIcon" alt="学历图标" class="w-20 h-20 opacity-40" />
</div>
<h3 class="text-lg font-medium text-gray-900 mb-2">暂无学历信息</h3>
<p class="text-sm text-gray-500 max-w-md">
系统中暂无相关的学历信息记录这可能是因为学历信息未公开或数据正在同步中
</p>
</div>
</div>
</template>
<style lang="scss" scoped>
.card {
padding: 1.5rem;
box-shadow: 0px 0px 24px 0px #3F3F3F0F;
border-radius: 12px;
background: white;
}
.bg-gray-50 {
transition: all 0.3s ease;
}
.bg-gray-50:hover {
transform: translateY(-2px);
}
</style>