t
This commit is contained in:
@@ -107,7 +107,7 @@
|
||||
/* ===== 业务特定颜色 ===== */
|
||||
--color-service-personal: #5d7eeb; /* 个人大数据 */
|
||||
--color-service-company: #6b9df9; /* 小微企业 */
|
||||
--color-service-loan: #e1a0e4; /* 贷前背调 */
|
||||
--color-service-loan: #e1a0e4; /* 贷前风险 */
|
||||
|
||||
/* ===== 渐变色彩 ===== */
|
||||
--gradient-primary: linear-gradient(
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
<p class="indent-[2em]">
|
||||
本人<span class="font-bold">
|
||||
{{ signature ? props.name : "____________" }}</span>
|
||||
拟向贵司申请大数据分析报告查询业务,贵司需要了解本人相关状况,用于查询大数据分析报告,因此本人同意向贵司提供本人的姓名和手机号等个人信息,并同意贵司向第三方(包括但不限于西部数据交易有限公司)传送上述信息。第三方将使用上述信息核实信息真实情况,查询信用记录,并生成报告。
|
||||
拟向贵司申请大数据分析报告查询业务,贵司需要了解本人相关状况,用于查询大数据分析报告,因此本人同意向贵司提供本人的姓名和手机号等个人信息,并同意贵司向第三方传送上述信息。第三方将使用上述信息核实信息真实情况,查询信用记录,并生成报告。
|
||||
</p>
|
||||
<p class="mt-2 font-bold">授权内容如下:</p>
|
||||
<ol class="list-decimal pl-6">
|
||||
<li>
|
||||
贵司向依法成立的第三方服务商(包括但不限于西部数据交易有限公司)根据本人提交的信息进行核实,并有权通过前述第三方服务机构查询、使用本人的身份信息、设备信息、运营商信息等,查询本人信息(包括但不限于学历、婚姻、资产状况及对信息主体产生负面影响的不良信息),出具相关报告。
|
||||
贵司向依法成立的第三方服务商根据本人提交的信息进行核实,并有权通过前述第三方服务机构查询、使用本人的身份信息、设备信息、运营商信息等,查询本人信息(包括但不限于学历、婚姻、资产状况及对信息主体产生负面影响的不良信息),出具相关报告。
|
||||
</li>
|
||||
<li>
|
||||
依法成立的第三方服务商查询或核实、搜集、保存、处理、共享、使用(含合法业务应用)本人相关数据,且不再另行告知本人,但法律、法规、监管政策禁止的除外。
|
||||
|
||||
@@ -336,6 +336,11 @@ const featureMap = {
|
||||
name: "学历信息",
|
||||
component: defineAsyncComponent(() => import("@/ui/CIVYZ7F3A.vue")),
|
||||
},
|
||||
IVYZ3P9M: {
|
||||
name: "学历信息",
|
||||
component: defineAsyncComponent(() => import("@/ui/IVYZ3P9M.vue")),
|
||||
remark: '学历信息展示学生姓名、身份证号、学校、专业、入学与毕业时间、学历层次以及学习形式等字段,可结合字典编码了解具体含义。',
|
||||
},
|
||||
DWBG8B4D: {
|
||||
name: "谛听多维报告",
|
||||
component: defineAsyncComponent(() => import("@/ui/CDWBG8B4D/index.vue")),
|
||||
@@ -579,6 +584,7 @@ const featureRiskLevels = {
|
||||
// 🔵 低风险类 - 权重 3
|
||||
'IVYZ5733': 3, // 婚姻状态
|
||||
'IVYZ9A2B': 3, // 学历信息
|
||||
'IVYZ3P9M': 3, // 学历信息查询(实时版)
|
||||
|
||||
// 📊 复合报告类 - 按子模块动态计算
|
||||
'DWBG8B4D': 0, // 谛听多维报告(由子模块计算)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<SectionTitle title="基本信息" />
|
||||
<div class="ml-auto flex items-center text-gray-600 cursor-pointer" @click="toExample">
|
||||
<img src="@/assets/images/report/slbg_inquire_icon.png" alt="示例报告" class="w-4 h-4 mr-1" />
|
||||
<span class="text-sm">示例报告</span>
|
||||
<span class="">示例报告</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 表单输入区域 -->
|
||||
@@ -42,9 +42,9 @@
|
||||
<button class="text-primary font-medium text-nowrap"
|
||||
:disabled="isCountingDown || !isPhoneNumberValid" @click="sendVerificationCode">
|
||||
{{
|
||||
isCountingDown
|
||||
? `${countdown}s重新获取`
|
||||
: "获取验证码"
|
||||
isCountingDown
|
||||
? `${countdown}s重新获取`
|
||||
: "获取验证码"
|
||||
}}
|
||||
</button>
|
||||
</div>
|
||||
@@ -66,10 +66,10 @@
|
||||
class="w-full bg-primary text-white py-4 rounded-[48px] text-lg font-medium mb-4 flex items-center justify-center mt-10"
|
||||
@click="handleSubmit">
|
||||
<span>{{ buttonText }}</span>
|
||||
<span class="ml-4">¥{{ featureData.sell_price || '88.8' }}</span>
|
||||
<span class="ml-4">¥{{ featureData.sell_price }}</span>
|
||||
</button>
|
||||
<div class="text-xs text-gray-500 leading-relaxed mt-8" v-html="featureData.description">
|
||||
</div>
|
||||
<!-- <div class="text-xs text-gray-500 leading-relaxed mt-8" v-html="featureData.description">
|
||||
</div> -->
|
||||
<!-- 免责声明 -->
|
||||
<div class="text-xs text-center text-gray-500 leading-relaxed mt-2">
|
||||
为保证用户的隐私及数据安全,查询结果生成30天后将自动删除
|
||||
|
||||
6416
src/data/ivyz3p9m-dictionary.json
Normal file
6416
src/data/ivyz3p9m-dictionary.json
Normal file
File diff suppressed because it is too large
Load Diff
696
src/ui/IVYZ3P9M.vue
Normal file
696
src/ui/IVYZ3P9M.vue
Normal file
@@ -0,0 +1,696 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { useRiskNotifier } from '@/composables/useRiskNotifier';
|
||||
|
||||
import xlIcon from '@/assets/images/report/xl.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 dictionaries from '@/data/ivyz3p9m-dictionary.json';
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: [Array, Object],
|
||||
default: () => [],
|
||||
},
|
||||
apiId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
notifyRiskStatus: {
|
||||
type: Function,
|
||||
default: () => { },
|
||||
},
|
||||
});
|
||||
|
||||
const riskScore = computed(() => 100);
|
||||
useRiskNotifier(props, riskScore);
|
||||
defineExpose({ riskScore });
|
||||
const educationLevelMap = dictionaries.educationLevel ?? {};
|
||||
const learningFormMap = dictionaries.learningForm ?? {};
|
||||
const schoolDictionary = dictionaries.schools ?? {};
|
||||
const specialtyDictionary = dictionaries.specialties ?? {};
|
||||
|
||||
const educationTagColorMap = {
|
||||
'1': 'bg-emerald-50 text-emerald-700 border-emerald-200',
|
||||
'2': 'bg-blue-50 text-blue-700 border-blue-200',
|
||||
'3': 'bg-indigo-50 text-indigo-700 border-indigo-200',
|
||||
'4': 'bg-purple-50 text-purple-700 border-purple-200',
|
||||
'5': 'bg-amber-50 text-amber-700 border-amber-200',
|
||||
};
|
||||
|
||||
const learningFormColorMap = {
|
||||
'1': 'bg-sky-50 text-sky-700 border-sky-200',
|
||||
'2': 'bg-blue-50 text-blue-700 border-blue-200',
|
||||
'3': 'bg-blue-50 text-blue-700 border-blue-200',
|
||||
'4': 'bg-cyan-50 text-cyan-700 border-cyan-200',
|
||||
'5': 'bg-orange-50 text-orange-700 border-orange-200',
|
||||
'6': 'bg-lime-50 text-lime-700 border-lime-200',
|
||||
'7': 'bg-indigo-50 text-indigo-700 border-indigo-200',
|
||||
'8': 'bg-violet-50 text-violet-700 border-violet-200',
|
||||
'9': 'bg-fuchsia-50 text-fuchsia-700 border-fuchsia-200',
|
||||
};
|
||||
|
||||
const normalizeCode = (value) => {
|
||||
if (value === null || value === undefined) return '';
|
||||
return String(value).trim();
|
||||
};
|
||||
|
||||
const getEducationLevelText = (code) => {
|
||||
const normalized = normalizeCode(code);
|
||||
if (!normalized) return '未知';
|
||||
return educationLevelMap[normalized] || '未知';
|
||||
};
|
||||
|
||||
const getLearningFormText = (code) => {
|
||||
const normalized = normalizeCode(code);
|
||||
if (!normalized) return '未知';
|
||||
return learningFormMap[normalized] || '未知';
|
||||
};
|
||||
|
||||
const getSchoolNameText = (code, fallback) => {
|
||||
const normalized = normalizeCode(code);
|
||||
if (!normalized) return fallback || '未知学校';
|
||||
return schoolDictionary[normalized] || fallback || '未知学校';
|
||||
};
|
||||
|
||||
const getSpecialtyNameText = (code, fallback) => {
|
||||
const normalized = normalizeCode(code);
|
||||
if (!normalized) return fallback || '未知专业';
|
||||
return specialtyDictionary[normalized] || fallback || '未知专业';
|
||||
};
|
||||
|
||||
const getEducationLevelClass = (code) => {
|
||||
const normalized = normalizeCode(code);
|
||||
return educationTagColorMap[normalized] || 'bg-gray-50 text-gray-700 border-gray-200';
|
||||
};
|
||||
|
||||
const getLearningFormClass = (code) => {
|
||||
const normalized = normalizeCode(code);
|
||||
return learningFormColorMap[normalized] || 'bg-gray-50 text-gray-700 border-gray-200';
|
||||
};
|
||||
|
||||
const maskIdNumber = (idNumber) => {
|
||||
if (!idNumber) return '未知';
|
||||
const normalized = String(idNumber).trim();
|
||||
if (normalized.length <= 6) {
|
||||
return `${normalized.slice(0, 1)}****${normalized.slice(-1)}`;
|
||||
}
|
||||
return `${normalized.slice(0, 3)}********${normalized.slice(-4)}`;
|
||||
};
|
||||
|
||||
const formatDate = (dateStr) => {
|
||||
if (!dateStr) return '未知';
|
||||
const normalized = String(dateStr).trim();
|
||||
if (!/^\d+$/.test(normalized)) return '未知';
|
||||
|
||||
if (normalized.length === 8) {
|
||||
const year = normalized.substring(0, 4);
|
||||
const month = normalized.substring(4, 6);
|
||||
const day = normalized.substring(6, 8);
|
||||
return `${year}年${month}月${day}日`;
|
||||
}
|
||||
|
||||
if (normalized.length === 6) {
|
||||
const year = normalized.substring(0, 4);
|
||||
const month = normalized.substring(4, 6);
|
||||
return `${year}年${month}月`;
|
||||
}
|
||||
|
||||
if (normalized.length === 4) {
|
||||
const shortYear = normalized.substring(0, 2);
|
||||
const month = normalized.substring(2, 4);
|
||||
return `20${shortYear}年${month}月`;
|
||||
}
|
||||
|
||||
return '未知';
|
||||
};
|
||||
|
||||
const parseDate = (value) => {
|
||||
if (!value) return null;
|
||||
const normalized = String(value).trim();
|
||||
if (!/^\d+$/.test(normalized)) return null;
|
||||
|
||||
let year;
|
||||
let month;
|
||||
let day = 1;
|
||||
|
||||
if (normalized.length === 8) {
|
||||
year = Number(normalized.substring(0, 4));
|
||||
month = Number(normalized.substring(4, 6));
|
||||
day = Number(normalized.substring(6, 8));
|
||||
} else if (normalized.length === 6) {
|
||||
year = Number(normalized.substring(0, 4));
|
||||
month = Number(normalized.substring(4, 6));
|
||||
} else if (normalized.length === 4) {
|
||||
year = Number(`20${normalized.substring(0, 2)}`);
|
||||
month = Number(normalized.substring(2, 4));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!year || !month) return null;
|
||||
return new Date(year, month - 1, day);
|
||||
};
|
||||
|
||||
const calculateStudyDuration = (start, end) => {
|
||||
const startDate = parseDate(start);
|
||||
const endDate = parseDate(end);
|
||||
|
||||
if (!startDate || !endDate || endDate < startDate) {
|
||||
return '时长未知';
|
||||
}
|
||||
|
||||
const totalMonths =
|
||||
(endDate.getFullYear() - startDate.getFullYear()) * 12 +
|
||||
(endDate.getMonth() - startDate.getMonth());
|
||||
|
||||
if (totalMonths <= 0) {
|
||||
return '不足 1 个月';
|
||||
}
|
||||
|
||||
const years = Math.floor(totalMonths / 12);
|
||||
const months = totalMonths % 12;
|
||||
|
||||
const parts = [];
|
||||
if (years > 0) parts.push(`${years}年`);
|
||||
if (months > 0) parts.push(`${months}个月`);
|
||||
|
||||
return parts.length > 0 ? `约 ${parts.join('')}` : '约 1 个月';
|
||||
};
|
||||
|
||||
const educationRecords = computed(() => {
|
||||
const source = props.data;
|
||||
if (Array.isArray(source)) return source;
|
||||
if (Array.isArray(source?.data)) return source.data;
|
||||
if (Array.isArray(source?.records)) return source.records;
|
||||
if (Array.isArray(source?.list)) return source.list;
|
||||
return [];
|
||||
});
|
||||
|
||||
const enhancedRecords = computed(() =>
|
||||
educationRecords.value.map((record, index) => {
|
||||
const educationLevelCode = normalizeCode(record.educationLevel);
|
||||
const learningFormCode = normalizeCode(record.learningForm);
|
||||
const schoolCode = normalizeCode(record.schoolName);
|
||||
const specialtyCode = normalizeCode(record.specialtyName);
|
||||
|
||||
const schoolName = getSchoolNameText(schoolCode, record.schoolName);
|
||||
const specialtyName = getSpecialtyNameText(specialtyCode, record.specialtyName);
|
||||
|
||||
return {
|
||||
index: index + 1,
|
||||
studentName: record.studentName || '未知',
|
||||
idNumber: record.idNumber || '',
|
||||
maskedIdNumber: maskIdNumber(record.idNumber),
|
||||
schoolName,
|
||||
specialtyName,
|
||||
isUnknownSchool: schoolName === '未知学校' || (!schoolCode && !record.schoolName),
|
||||
isUnknownSpecialty: specialtyName === '未知专业' || (!specialtyCode && !record.specialtyName),
|
||||
educationLevelCode,
|
||||
educationLevel: getEducationLevelText(educationLevelCode),
|
||||
learningFormCode,
|
||||
learningForm: getLearningFormText(learningFormCode),
|
||||
enrollmentDate: formatDate(record.enrollmentDate),
|
||||
graduationDate: formatDate(record.graduationDate),
|
||||
rawEnrollmentDate: record.enrollmentDate || '',
|
||||
rawGraduationDate: record.graduationDate || '',
|
||||
studyDuration: calculateStudyDuration(record.enrollmentDate, record.graduationDate),
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
const getTimestamp = (value) => {
|
||||
const date = parseDate(value);
|
||||
return date ? date.getTime() : null;
|
||||
};
|
||||
|
||||
const orderedRecords = computed(() => {
|
||||
if (enhancedRecords.value.length <= 1) return enhancedRecords.value;
|
||||
|
||||
return [...enhancedRecords.value].sort((a, b) => {
|
||||
const startA =
|
||||
getTimestamp(a.rawEnrollmentDate) ??
|
||||
getTimestamp(a.rawGraduationDate) ??
|
||||
Number.MAX_SAFE_INTEGER;
|
||||
const startB =
|
||||
getTimestamp(b.rawEnrollmentDate) ??
|
||||
getTimestamp(b.rawGraduationDate) ??
|
||||
Number.MAX_SAFE_INTEGER;
|
||||
|
||||
if (startA === startB) {
|
||||
const endA = getTimestamp(a.rawGraduationDate) ?? Number.MAX_SAFE_INTEGER;
|
||||
const endB = getTimestamp(b.rawGraduationDate) ?? Number.MAX_SAFE_INTEGER;
|
||||
return endA - endB;
|
||||
}
|
||||
|
||||
return startA - startB;
|
||||
});
|
||||
});
|
||||
|
||||
const educationRankMap = {
|
||||
'1': 1,
|
||||
'2': 2,
|
||||
'3': 3,
|
||||
'4': 4,
|
||||
'5': 2.5,
|
||||
};
|
||||
|
||||
const getEducationRank = (code) => {
|
||||
const normalized = normalizeCode(code);
|
||||
return educationRankMap[normalized] ?? 0;
|
||||
};
|
||||
|
||||
const summaryRecord = computed(() => {
|
||||
if (orderedRecords.value.length === 0) return null;
|
||||
|
||||
return orderedRecords.value.reduce((best, current) => {
|
||||
if (!best) return current;
|
||||
|
||||
const currentRank = getEducationRank(current.educationLevelCode);
|
||||
const bestRank = getEducationRank(best.educationLevelCode);
|
||||
|
||||
if (currentRank > bestRank) return current;
|
||||
if (currentRank < bestRank) return best;
|
||||
|
||||
const currentGrad = getTimestamp(current.rawGraduationDate) ?? Number.NEGATIVE_INFINITY;
|
||||
const bestGrad = getTimestamp(best.rawGraduationDate) ?? Number.NEGATIVE_INFINITY;
|
||||
|
||||
return currentGrad >= bestGrad
|
||||
? current
|
||||
: best;
|
||||
}, null);
|
||||
});
|
||||
|
||||
const latestGraduationText = computed(() => {
|
||||
if (orderedRecords.value.length === 0) return '未知';
|
||||
|
||||
const latest = orderedRecords.value.reduce((latestRecord, current) => {
|
||||
if (!latestRecord) return current;
|
||||
const currentGrad = getTimestamp(current.rawGraduationDate) ?? Number.NEGATIVE_INFINITY;
|
||||
const latestGrad = getTimestamp(latestRecord.rawGraduationDate) ?? Number.NEGATIVE_INFINITY;
|
||||
return currentGrad >= latestGrad
|
||||
? current
|
||||
: latestRecord;
|
||||
}, null);
|
||||
|
||||
return latest?.graduationDate || '未知';
|
||||
});
|
||||
|
||||
const hasData = computed(() => orderedRecords.value.length > 0);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="hasData" class="card max-w-4xl mx-auto">
|
||||
<div class="flex flex-col gap-6">
|
||||
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-start md:items-end gap-1">
|
||||
<div class="text-lg font-semibold text-blue-600">
|
||||
共 {{ orderedRecords.length }} 条记录
|
||||
</div>
|
||||
<div v-if="summaryRecord" class="summary-meta text-sm text-gray-500">
|
||||
<span class="summary-meta__item">最高学历:{{ summaryRecord.educationLevel }}</span>
|
||||
<span v-if="latestGraduationText" class="summary-meta__divider">·</span>
|
||||
<span class="summary-meta__item">最新毕业时间:{{ latestGraduationText }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="summaryRecord" class="summary-banner">
|
||||
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-6">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="w-14 h-14 rounded-full bg-white/80 flex items-center justify-center shadow-inner">
|
||||
<img :src="xlIcon" alt="学历图标" class="w-10 h-10" />
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-xl font-semibold text-gray-900">{{ summaryRecord.studentName }}</div>
|
||||
<div class="text-sm text-slate-600">身份证:{{ summaryRecord.maskedIdNumber }}</div>
|
||||
<div class="summary-highlight">
|
||||
<span class="summary-highlight__badge">{{ summaryRecord.educationLevel }}</span>
|
||||
<div class="summary-highlight__text flex flex-col gap-1">
|
||||
<span class="flex items-center gap-2">
|
||||
{{ summaryRecord.schoolName }}
|
||||
<span v-if="summaryRecord.isUnknownSchool" class="unknown-hint">
|
||||
<svg class="unknown-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span v-if="summaryRecord.isUnknownSchool" class="unknown-text">该学校名称信息未找到,可能是学校已改名</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="flex flex-wrap items-center gap-3">
|
||||
<div class="summary-chip">
|
||||
<span class="chip-label">入学时间</span>
|
||||
<span class="chip-value">{{ summaryRecord.enrollmentDate }}</span>
|
||||
</div>
|
||||
<div class="summary-chip">
|
||||
<span class="chip-label">毕业时间</span>
|
||||
<span class="chip-value">{{ summaryRecord.graduationDate }}</span>
|
||||
</div>
|
||||
<div class="summary-chip">
|
||||
<span class="chip-label">学习时长</span>
|
||||
<span class="chip-value">{{ summaryRecord.studyDuration }}</span>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-5">
|
||||
<div v-for="record in orderedRecords" :key="record.index" class="record-card">
|
||||
<div class="flex flex-col lg:flex-row lg:items-start lg:justify-between gap-4">
|
||||
<div class="record-header">
|
||||
<div class="record-index">
|
||||
{{ record.index }}
|
||||
</div>
|
||||
<div class="record-title">
|
||||
<div class="record-title__name flex flex-col gap-1">
|
||||
<span class="flex items-center gap-2">
|
||||
{{ record.schoolName }}
|
||||
<span v-if="record.isUnknownSchool" class="unknown-hint">
|
||||
<svg class="unknown-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span v-if="record.isUnknownSchool" class="unknown-text">该学校名称信息未找到,可能是学校已改名</span>
|
||||
</div>
|
||||
<div class="record-title__meta" v-if="record.enrollmentDate !== '未知' || record.graduationDate !== '未知'">
|
||||
<span v-if="record.enrollmentDate !== '未知'">{{ record.enrollmentDate }}</span>
|
||||
<span v-if="record.enrollmentDate !== '未知' && record.graduationDate !== '未知'"> - </span>
|
||||
<span v-if="record.graduationDate !== '未知'">{{ record.graduationDate }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-3">
|
||||
<span :class="['tag', getEducationLevelClass(record.educationLevelCode)]">
|
||||
{{ record.educationLevel }}学历
|
||||
</span>
|
||||
<span :class="['tag', getLearningFormClass(record.learningFormCode)]">
|
||||
学习形式:{{ record.learningForm }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-6">
|
||||
<div class="info-block">
|
||||
<div class="info-icon">
|
||||
<img :src="zymcIcon" alt="专业名称" class="w-7 h-7" />
|
||||
</div>
|
||||
<div>
|
||||
<div class="info-label">专业名称</div>
|
||||
<div class="info-value flex flex-col gap-1">
|
||||
<span class="flex items-center gap-2">
|
||||
{{ record.specialtyName }}
|
||||
<span v-if="record.isUnknownSpecialty" class="unknown-hint">
|
||||
<svg class="unknown-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span v-if="record.isUnknownSpecialty" class="unknown-text">该专业名称信息未找到,可能是该学校专业已受到变动</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-block">
|
||||
<div class="info-icon">
|
||||
<img :src="xxxsIcon" alt="学习形式" class="w-7 h-7" />
|
||||
</div>
|
||||
<div>
|
||||
<div class="info-label">学习形式</div>
|
||||
<div class="info-value">
|
||||
{{ record.learningForm }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-block">
|
||||
<div class="info-icon">
|
||||
<img :src="xxlxIcon" alt="入学时间" class="w-7 h-7" />
|
||||
</div>
|
||||
<div>
|
||||
<div class="info-label">入学时间</div>
|
||||
<div class="info-value">{{ record.enrollmentDate }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-block">
|
||||
<div class="info-icon">
|
||||
<img :src="bysjIcon" alt="毕业时间" class="w-7 h-7" />
|
||||
</div>
|
||||
<div>
|
||||
<div class="info-label">毕业时间</div>
|
||||
<div class="info-value">{{ record.graduationDate }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="card max-w-3xl 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;
|
||||
}
|
||||
|
||||
.summary-banner {
|
||||
border-radius: 16px;
|
||||
padding: 1.5rem;
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.1), rgba(79, 70, 229, 0.12));
|
||||
border: 1px solid rgba(59, 130, 246, 0.25);
|
||||
}
|
||||
|
||||
.summary-chip {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
gap: 0.15rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-radius: 0.75rem;
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
border: 1px solid rgba(148, 163, 184, 0.3);
|
||||
}
|
||||
|
||||
.chip-label {
|
||||
font-size: 0.7rem;
|
||||
color: #64748b;
|
||||
letter-spacing: 0.02em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.chip-value {
|
||||
font-size: 0.95rem;
|
||||
font-weight: 600;
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.summary-meta {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.summary-meta__divider {
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.summary-highlight {
|
||||
margin-top: 0.35rem;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.summary-highlight__badge {
|
||||
padding: 0.2rem 0.6rem;
|
||||
border-radius: 9999px;
|
||||
background: rgba(59, 130, 246, 0.12);
|
||||
color: #2563eb;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.summary-highlight__text {
|
||||
font-size: 0.9rem;
|
||||
color: #1e293b;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.record-card {
|
||||
position: relative;
|
||||
padding: 1.5rem;
|
||||
border-radius: 16px;
|
||||
border: 1px solid rgba(226, 232, 240, 0.9);
|
||||
background: linear-gradient(180deg, #ffffff 0%, #f8fafc 100%);
|
||||
box-shadow: 0 10px 25px rgba(15, 23, 42, 0.06);
|
||||
transition: all 0.25s ease;
|
||||
}
|
||||
|
||||
.record-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
background: linear-gradient(90deg, rgba(59, 130, 246, 0.75), rgba(129, 140, 248, 0.75));
|
||||
border-radius: 12px 12px 0 0;
|
||||
}
|
||||
|
||||
.record-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 16px 35px rgba(59, 130, 246, 0.16);
|
||||
}
|
||||
|
||||
.record-header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.record-index {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
border-radius: 999px;
|
||||
background: rgba(59, 130, 246, 0.18);
|
||||
color: #2563eb;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.05rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.record-title {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.2rem;
|
||||
}
|
||||
|
||||
.record-title__name {
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.record-title__meta {
|
||||
font-size: 0.85rem;
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
padding: 0.4rem 0.85rem;
|
||||
border-radius: 9999px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.info-block {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
padding: 1rem;
|
||||
border-radius: 12px;
|
||||
background-color: rgba(248, 250, 252, 0.9);
|
||||
border: 1px solid rgba(226, 232, 240, 0.8);
|
||||
transition: border-color 0.2s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
.info-block:hover {
|
||||
border-color: rgba(59, 130, 246, 0.3);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.info-icon {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
border-radius: 0.75rem;
|
||||
background: rgba(59, 130, 246, 0.12);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 0.75rem;
|
||||
color: #64748b;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
color: #0f172a;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.unknown-hint {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.unknown-icon {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
color: #f59e0b;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.unknown-text {
|
||||
font-size: 0.75rem;
|
||||
color: #f59e0b;
|
||||
line-height: 1.4;
|
||||
margin-top: 0.125rem;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.record-card {
|
||||
padding: 1.25rem;
|
||||
}
|
||||
|
||||
.info-block {
|
||||
padding: 0.85rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
<p class="my-2">海南天远大数据科技有限公司:</p>
|
||||
<p class="indent-[2em]">
|
||||
<!-- <span class="font-bold"> {{ signature ? userData.name : "____________" }}</span> -->
|
||||
本人________拟向贵司申请大数据分析报告查询业务,贵司需要了解本人相关状况,用于查询大数据分析报告,因此本人同意向贵司提供本人的姓名和手机号等个人信息,并同意贵司向第三方(包括但不限于西部数据交易有限公司)传送上述信息。第三方将使用上述信息核实信息真实情况,查询信用记录,并生成报告。
|
||||
本人________拟向贵司申请大数据分析报告查询业务,贵司需要了解本人相关状况,用于查询大数据分析报告,因此本人同意向贵司提供本人的姓名和手机号等个人信息,并同意贵司向第三方传送上述信息。第三方将使用上述信息核实信息真实情况,查询信用记录,并生成报告。
|
||||
</p>
|
||||
<p class="mt-2 font-bold">授权内容如下:</p>
|
||||
<ol class="list-decimal pl-6">
|
||||
<li>
|
||||
贵司向依法成立的第三方服务商(包括但不限于西部数据交易有限公司)根据本人提交的信息进行核实,并有权通过前述第三方服务机构查询、使用本人的身份信息、设备信息、运营商信息等,查询本人信息(包括但不限于学历、婚姻、资产状况及对信息主体产生负面影响的不良信息),出具相关报告。
|
||||
贵司向依法成立的第三方服务商根据本人提交的信息进行核实,并有权通过前述第三方服务机构查询、使用本人的身份信息、设备信息、运营商信息等,查询本人信息(包括但不限于学历、婚姻、资产状况及对信息主体产生负面影响的不良信息),出具相关报告。
|
||||
</li>
|
||||
<li>
|
||||
依法成立的第三方服务商查询或核实、搜集、保存、处理、共享、使用(含合法业务应用)本人相关数据,且不再另行告知本人,但法律、法规、监管政策禁止的除外。
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup>
|
||||
const router = useRouter();
|
||||
import { storeToRefs } from "pinia";
|
||||
import { showConfirmDialog } from "vant";
|
||||
import SectionTitle from "@/components/SectionTitle.vue";
|
||||
|
||||
const agentStore = useAgentStore();
|
||||
@@ -11,7 +12,25 @@ import loanCheckIcon from "@/assets/images/index/loan_check_bg.png";
|
||||
import marriageRiskIcon from "@/assets/images/index/marriage_risk_bg.png";
|
||||
import housekeepingRiskIcon from "@/assets/images/index/housekeeping_risk_bg.png";
|
||||
import preLoanRiskIcon from "@/assets/images/index/preloan_risk_bg.png";
|
||||
|
||||
function toInquire(name) {
|
||||
if (name === "marriage") {
|
||||
showConfirmDialog({
|
||||
title: "婚恋风险查询",
|
||||
message: "是否进入天远查进行婚恋查询?",
|
||||
confirmButtonText: "进入",
|
||||
cancelButtonText: "取消",
|
||||
})
|
||||
.then(() => {
|
||||
// 在当前标签页打开,不新开tab
|
||||
window.location.href = "https://www.tianyuancha.cn";
|
||||
})
|
||||
.catch(() => {
|
||||
// 取消则继续后续逻辑
|
||||
router.push(`/inquire/marriage`);
|
||||
});
|
||||
return; // 阻止继续跳转,等待 dialog 回调
|
||||
}
|
||||
router.push(`/inquire/${name}`);
|
||||
}
|
||||
function toInvitation() {
|
||||
@@ -76,7 +95,7 @@ const riskServices = ref([
|
||||
goColor: "#66cccc",
|
||||
},
|
||||
{
|
||||
title: "贷前背调",
|
||||
title: "贷前风险",
|
||||
name: "preloanbackgroundcheck",
|
||||
subtitle: "信用评估,放款无忧",
|
||||
bg: loanCheckIcon,
|
||||
@@ -143,7 +162,7 @@ const toBigData = () => {
|
||||
:style="`background: url(${service.bg}) no-repeat; background-size: cover; background-position: center;`"
|
||||
@click=" toInquire(service.name)">
|
||||
<div class="min-h-18 flex flex-col items-start px-1">
|
||||
<div class="mt-1 max-w-max text-left text-gray-600 font-bold text-md">
|
||||
<div class="mt-1 max-w-max text-left text-gray-600 font-bold">
|
||||
{{ service.title }}
|
||||
</div>
|
||||
<!-- <div class="max-w-max text-left text-xs text-gray-600">
|
||||
@@ -165,7 +184,7 @@ const toBigData = () => {
|
||||
:style="`background: url(${service.bg}) no-repeat; background-size: cover; background-position: center;`"
|
||||
@click="toInquire(service.name)">
|
||||
<div class="min-h-18 flex flex-col items-start px-1">
|
||||
<div class="mt-1 max-w-max text-left text-gray-600 font-bold text-sm">
|
||||
<div class="mt-1 max-w-max text-left text-gray-600 font-bold">
|
||||
{{ service.title }}
|
||||
</div>
|
||||
<!-- <div class="max-w-max text-left text-xs text-gray-600">
|
||||
|
||||
Reference in New Issue
Block a user