Files
tydata-webview-v2/src/ui/CIVYZ7F3A.vue
2025-10-30 13:34:28 +08:00

297 lines
12 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 { computed, onMounted } from 'vue';
import { useRiskNotifier } from '@/composables/useRiskNotifier';
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';
// 计算风险评分0-100分分数越高越安全
const riskScore = computed(() => {
// 学历信息不算风险始终返回100分最安全
return 100;
});
// 使用 composable 通知父组件风险评分
useRiskNotifier(props, riskScore);
// 暴露给父组件
defineExpose({
riskScore
});
// 格式化日期从YYYYMM格式转换为YYYY年MM月格式
const formatDate = (dateStr) => {
if (!dateStr || dateStr.length !== 6) return "未知";
const year = dateStr.substring(0, 4);
const month = dateStr.substring(4, 6);
return `${year}${month}`;
};
// 获取学历等级的描述
const getEducationLevelDesc = (level) => {
const descriptions = {
"专科": "专科学历是高等教育的重要组成部分,培养具有专业知识和技能的应用型人才。",
"本科": "本科学历是高等教育的基础学位,培养具有系统专业知识和基本技能的高级人才。",
"硕士": "硕士学位是较高层次的学位,培养具有较深厚理论基础和专业技能的高级专门人才。",
"博士": "博士学位是最高学位,培养能够独立从事科学研究工作、具有创新能力的高级专门人才。",
};
return descriptions[level] || "";
};
// 根据学校属性获取徽章配置
const getSchoolBadges = () => {
const badges = [];
if (props.data.isProject985 === "是") {
badges.push({
text: "985院校",
class: "bg-amber-500 text-white",
icon: "🏆"
});
}
if (props.data.isProject211 === "是") {
badges.push({
text: "211院校",
class: "bg-blue-500 text-white",
icon: "⭐"
});
}
if (props.data.isDoubleFirstClass === "是") {
badges.push({
text: "双一流",
class: "bg-green-500 text-white",
icon: "✨"
});
}
return badges;
};
// 获取学校类型徽章样式
const getSchoolTypeBadgeClass = (type) => {
const typeClasses = {
"综合": "bg-blue-50 text-blue-700 border-blue-300",
"理工": "bg-purple-50 text-purple-700 border-purple-300",
"农业": "bg-green-50 text-green-700 border-green-300",
"医学": "bg-red-50 text-red-700 border-red-300",
"师范": "bg-yellow-50 text-yellow-700 border-yellow-300",
"财经": "bg-cyan-50 text-cyan-700 border-cyan-300",
"艺术": "bg-pink-50 text-pink-700 border-pink-300",
};
return typeClasses[type] || "bg-gray-50 text-gray-700 border-gray-300";
};
// 获取软科排名样式
const getRankingClass = () => {
if (!props.data.Ranking) return "bg-gray-50 text-gray-700";
// 解析排名范围 (例如: "151-155")
const match = props.data.Ranking.match(/(\d+)-(\d+)/);
if (match) {
const minRank = parseInt(match[1]);
if (minRank <= 50) return "bg-green-50 text-green-700 border-green-300";
if (minRank <= 100) return "bg-blue-50 text-blue-700 border-blue-300";
if (minRank <= 200) return "bg-yellow-50 text-yellow-700 border-yellow-300";
}
return "bg-gray-50 text-gray-700 border-gray-300";
};
// 判断是否有数据
const hasData = computed(() => {
return props.data && Object.keys(props.data).length > 0;
});
// 获取徽章列表
const schoolBadges = computed(() => getSchoolBadges());
</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">{{ data.educationLevel }}学历</h2>
<p class="text-sm text-gray-500">Education Information</p>
</div>
</div>
</div>
</div>
<!-- 主要内容区域 -->
<div class="space-y-4">
<!-- 软科排名 -->
<div v-if="data.Ranking"
class="bg-gradient-to-r from-blue-50 to-indigo-50 rounded-lg p-4 border border-blue-200">
<div class="flex items-center gap-3">
<div class="w-8 h-8 flex items-center justify-center flex-shrink-0">
<img :src="rkpmIcon" alt="软科排名" class="w-8 h-8" />
</div>
<div class="flex-1">
<div class="text-sm text-gray-600 mb-1">软科排名</div>
<div
:class="['inline-block px-3 py-1 rounded-full text-sm font-medium border', getRankingClass()]">
{{ data.Ranking }}
</div>
</div>
</div>
</div>
<!-- 学校徽章 -->
<div v-if="schoolBadges.length > 0" class="flex gap-2 flex-wrap">
<div v-for="(badge, index) in schoolBadges" :key="index"
:class="['inline-flex items-center gap-1 px-4 py-2 rounded-lg text-sm font-medium shadow-sm', badge.class]">
<span>{{ badge.icon }}</span>
<span>{{ badge.text }}</span>
</div>
</div>
<!-- 详细信息卡片 -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<!-- 专业信息 -->
<div v-if="data.major"
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">{{ data.major }}</div>
</div>
</div>
</div>
<!-- 学校类型 -->
<div v-if="data.schoolType"
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="['inline-block px-3 py-1 rounded text-sm font-medium border', getSchoolTypeBadgeClass(data.schoolType)]">
{{ data.schoolType }}类院校
</div>
</div>
</div>
</div>
<!-- 学习形式 -->
<div v-if="data.educationType"
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">{{ data.educationType }}</div>
</div>
</div>
</div>
<!-- 毕业时间 -->
<div v-if="data.graduationDate"
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(data.graduationDate) }}</div>
</div>
</div>
</div>
</div>
<!-- 学历描述 -->
<div v-if="data.educationLevel"
class="mt-6 bg-gradient-to-r from-blue-50 to-indigo-50 rounded-lg p-5 border border-blue-200">
<div class="flex items-start gap-3">
<div class="w-10 h-10 rounded-full bg-blue-500 flex items-center justify-center flex-shrink-0 mt-1">
<span class="text-white text-xl">💡</span>
</div>
<div class="flex-1">
<div class="flex items-center gap-2 mb-2">
<h3 class="text-lg font-semibold text-gray-900">学历说明</h3>
<span class="px-2 py-1 bg-blue-500 text-white text-xs rounded">信息</span>
</div>
<p class="text-gray-700 leading-relaxed">
{{ getEducationLevelDesc(data.educationLevel) }}
</p>
</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>