|
@@ -713,6 +713,15 @@ onMounted(() => {
|
|
|
console.log('哈希:', window.location.hash)
|
|
|
|
|
|
fetchApplicationDetail()
|
|
|
+
|
|
|
+ // 确保所有主要部分都有正确的ID
|
|
|
+ setTimeout(() => {
|
|
|
+ console.log('检查页面ID:');
|
|
|
+ ['comprehensive-assessment', 'image-analysis', 'answer-records', 'other-info'].forEach(id => {
|
|
|
+ const element = document.getElementById(id);
|
|
|
+ console.log(`ID ${id} 存在:`, !!element);
|
|
|
+ });
|
|
|
+ }, 1000);
|
|
|
})
|
|
|
|
|
|
const evaluationScore = ref<number>(0)
|
|
@@ -1050,6 +1059,55 @@ const formatDate = (dateString: string | null | undefined): string => {
|
|
|
const handleViewProfile = () => {
|
|
|
fetchUserProfile();
|
|
|
};
|
|
|
+
|
|
|
+const handleTabClick = (tab: any) => {
|
|
|
+ console.log('点击标签:', tab.props.name);
|
|
|
+
|
|
|
+ // 尝试多种方法找到目标元素
|
|
|
+ const targetId = tab.props.name;
|
|
|
+ const element = document.getElementById(targetId);
|
|
|
+
|
|
|
+ if (element) {
|
|
|
+ // 找到滚动容器 - 可能是document.body, document.documentElement, 或特定容器
|
|
|
+ const scrollContainer = document.querySelector('.max-w-4xl') ||
|
|
|
+ document.documentElement ||
|
|
|
+ document.body;
|
|
|
+
|
|
|
+ // 计算元素相对于滚动容器的位置
|
|
|
+ const containerRect = scrollContainer.getBoundingClientRect();
|
|
|
+ const elementRect = element.getBoundingClientRect();
|
|
|
+ const relativeTop = elementRect.top - containerRect.top;
|
|
|
+
|
|
|
+ // 滚动容器
|
|
|
+ if (scrollContainer === document.documentElement || scrollContainer === document.body) {
|
|
|
+ window.scrollTo({
|
|
|
+ top: window.scrollY + relativeTop - 100, // 减去100px的偏移
|
|
|
+ behavior: 'smooth'
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ scrollContainer.scrollTo({
|
|
|
+ top: scrollContainer.scrollTop + relativeTop - 100,
|
|
|
+ behavior: 'smooth'
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('执行滚动:', window.scrollY + relativeTop - 100);
|
|
|
+ } else {
|
|
|
+ console.error('未找到目标元素:', targetId);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 添加一个备用的滚动函数,可以通过按钮直接调用
|
|
|
+const scrollToSection = (sectionId: string) => {
|
|
|
+ console.log('尝试滚动到部分:', sectionId);
|
|
|
+ const element = document.getElementById(sectionId);
|
|
|
+ if (element) {
|
|
|
+ element.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
|
+ setTimeout(() => {
|
|
|
+ window.scrollBy({ top: -100, behavior: 'smooth' });
|
|
|
+ }, 100);
|
|
|
+ }
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
@@ -1126,85 +1184,119 @@ const handleViewProfile = () => {
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 1. 综合评估 -->
|
|
|
- <div class="mb-8">
|
|
|
- <h2 class="text-xl font-bold mb-6">1. 综合评估</h2>
|
|
|
- <div class="space-y-4">
|
|
|
- <div class="border-b pb-4">
|
|
|
- <div class="flex items-center justify-between mb-2">
|
|
|
- <span class="text-gray-600">录用建议</span>
|
|
|
- <span :class="{
|
|
|
- 'text-green-500': candidateInfo.hireRecommendation?.includes('推荐'),
|
|
|
- 'text-red-500': candidateInfo.hireRecommendation?.includes('不推荐'),
|
|
|
- 'text-yellow-500': !candidateInfo.hireRecommendation?.includes('推荐') && !candidateInfo.hireRecommendation?.includes('不推荐')
|
|
|
- }">{{ candidateInfo.hireRecommendation || '无建议' }}</span>
|
|
|
+ <!-- 在标签导航下方添加备用导航按钮 -->
|
|
|
+ <!-- <div class="backup-navigation mt-4 mb-6 flex flex-wrap gap-2">
|
|
|
+ <el-button size="small" @click="scrollToSection('comprehensive-assessment')">
|
|
|
+ 综合评估
|
|
|
+ </el-button>
|
|
|
+ <el-button size="small" @click="scrollToSection('image-analysis')">
|
|
|
+ 图片分析
|
|
|
+ </el-button>
|
|
|
+ <el-button size="small" @click="scrollToSection('answer-records')">
|
|
|
+ 回答记录
|
|
|
+ </el-button>
|
|
|
+ <el-button size="small" @click="scrollToSection('other-info')">
|
|
|
+ 其他信息
|
|
|
+ </el-button>
|
|
|
+ </div> -->
|
|
|
+
|
|
|
+ <!-- 将原来的标签导航移到更上层,并添加固定定位 -->
|
|
|
+ <div class="sticky-tabs">
|
|
|
+ <el-tabs @tab-click="handleTabClick">
|
|
|
+ <el-tab-pane label="综合评估" name="comprehensive-assessment"></el-tab-pane>
|
|
|
+ <el-tab-pane label="图片分析" name="image-analysis"></el-tab-pane>
|
|
|
+ <el-tab-pane label="回答记录" name="answer-records"></el-tab-pane>
|
|
|
+ <el-tab-pane label="其他信息" name="other-info"></el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 为每个主要章节添加id -->
|
|
|
+ <div id="comprehensive-assessment" class="mb-8 pt-4 border-t border-transparent">
|
|
|
+ <!-- 1. 综合评估 -->
|
|
|
+ <div class="mb-8">
|
|
|
+ <h2 class="text-xl font-bold mb-6">1. 综合评估</h2>
|
|
|
+
|
|
|
+ <div class="space-y-4">
|
|
|
+ <!-- 为每个部分添加 id -->
|
|
|
+ <div id="hire-recommendation" class="border-b pb-4">
|
|
|
+ <!-- 录用建议部分的现有代码 -->
|
|
|
+ <div class="border-b pb-4">
|
|
|
+ <div class="flex items-center justify-between mb-2">
|
|
|
+ <span class="text-gray-600">录用建议</span>
|
|
|
+ <span :class="{
|
|
|
+ 'text-green-500': candidateInfo.hireRecommendation?.includes('推荐'),
|
|
|
+ 'text-red-500': candidateInfo.hireRecommendation?.includes('不推荐'),
|
|
|
+ 'text-yellow-500': !candidateInfo.hireRecommendation?.includes('推荐') && !candidateInfo.hireRecommendation?.includes('不推荐')
|
|
|
+ }">{{ candidateInfo.hireRecommendation || '无建议' }}</span>
|
|
|
+ </div>
|
|
|
+ <p class="text-gray-600 text-sm">{{ candidateInfo.hireReason || '无详细说明' }}</p>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <p class="text-gray-600 text-sm">{{ candidateInfo.hireReason || '无详细说明' }}</p>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 添加红线题检测结果 -->
|
|
|
- <div class="border-b pb-4">
|
|
|
- <div class="flex items-center justify-between mb-2">
|
|
|
- <span class="text-gray-600" style="color: red;">红线题检测结果</span>
|
|
|
- <span :class="{
|
|
|
- 'text-green-500': apiData?.required_questions_summary?.all_correct,
|
|
|
- 'text-red-500': apiData?.required_questions_summary && !apiData.required_questions_summary.all_correct
|
|
|
- }">
|
|
|
- {{ apiData?.required_questions_summary?.all_correct ? '全部正确' : '存在错误,建议不录用' }}
|
|
|
- </span>
|
|
|
+
|
|
|
+ <div id="red-line" class="border-b pb-4">
|
|
|
+ <!-- 红线题检测部分的现有代码 -->
|
|
|
+ <div class="flex items-center justify-between mb-2">
|
|
|
+ <span class="text-gray-600" style="color: red;">红线题检测结果</span>
|
|
|
+ <span :class="{
|
|
|
+ 'text-green-500': apiData?.required_questions_summary?.all_correct,
|
|
|
+ 'text-red-500': apiData?.required_questions_summary && !apiData.required_questions_summary.all_correct
|
|
|
+ }">
|
|
|
+ {{ apiData?.required_questions_summary?.all_correct ? '全部正确' : '存在错误,建议不录用' }}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div v-if="apiData?.required_questions_summary && !apiData.required_questions_summary.all_correct"
|
|
|
+ class="mt-2 border-l-4 border-red-500 pl-3 bg-red-50 p-2 rounded">
|
|
|
+ <p class="text-red-700 font-medium mb-1">未通过的红线题:</p>
|
|
|
+ <ul v-if="apiData.required_questions_summary.failed_questions_details.length > 0"
|
|
|
+ class="list-disc pl-5 text-gray-600 text-sm">
|
|
|
+ <li v-for="(question, index) in apiData.required_questions_summary.failed_questions_details"
|
|
|
+ :key="'failed-'+index">
|
|
|
+ {{ question.question_text || `问题 ${index + 1}` }}
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ <p v-else class="text-gray-600 text-sm">未提供详细信息</p>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <div v-if="apiData?.required_questions_summary && !apiData.required_questions_summary.all_correct"
|
|
|
- class="mt-2 border-l-4 border-red-500 pl-3 bg-red-50 p-2 rounded">
|
|
|
- <p class="text-red-700 font-medium mb-1">未通过的红线题:</p>
|
|
|
- <ul v-if="apiData.required_questions_summary.failed_questions_details.length > 0"
|
|
|
- class="list-disc pl-5 text-gray-600 text-sm">
|
|
|
- <li v-for="(question, index) in apiData.required_questions_summary.failed_questions_details"
|
|
|
- :key="'failed-'+index">
|
|
|
- {{ question.question_text || `问题 ${index + 1}` }}
|
|
|
+
|
|
|
+ <div id="strengths" v-if="candidateInfo.strengths && candidateInfo.strengths.length > 0" class="border-b pb-4">
|
|
|
+ <h3 class="font-semibold mb-2">优点</h3>
|
|
|
+ <ul class="list-disc pl-5 text-gray-600 text-sm">
|
|
|
+ <li v-for="(strength, index) in candidateInfo.strengths" :key="'strength-'+index">
|
|
|
+ {{ strength }}
|
|
|
</li>
|
|
|
</ul>
|
|
|
- <p v-else class="text-gray-600 text-sm">未提供详细信息</p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div id="weaknesses" v-if="candidateInfo.weaknesses && candidateInfo.weaknesses.length > 0" class="border-b pb-4">
|
|
|
+ <h3 class="font-semibold mb-2">需改进的地方</h3>
|
|
|
+ <ul class="list-disc pl-5 text-gray-600 text-sm">
|
|
|
+ <li v-for="(weakness, index) in candidateInfo.weaknesses" :key="'weakness-'+index">
|
|
|
+ {{ weakness }}
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div id="duv-analysis" class="border-b pb-4">
|
|
|
+ <!-- DUV心理测评部分的现有代码 -->
|
|
|
+ <div class="flex items-center justify-between mt-4 mb-2">
|
|
|
+ <span class="text-gray-600">DUV 心理测评得分</span>
|
|
|
+ <span :class="getDuvScoreClass(apiData?.scoring_summary?.total_score_obtained)">
|
|
|
+ {{ getSafeScoreValue(apiData?.scoring_summary?.total_score_obtained) }}
|
|
|
+ <span class="ml-2 text-sm">({{ getDuvScoreLevel(apiData?.scoring_summary?.total_score_obtained) }})</span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <p class="text-gray-600 text-sm">
|
|
|
+ {{ getDuvScoreInterpretation(apiData?.scoring_summary?.total_score_obtained) }}
|
|
|
+ </p>
|
|
|
+ <p class="text-sm mt-1" :class="getDuvScoreClass(apiData?.scoring_summary?.total_score_obtained)">
|
|
|
+ <strong>录用建议:</strong> {{ getDuvHireRecommendation(apiData?.scoring_summary?.total_score_obtained) }}
|
|
|
+ </p>
|
|
|
</div>
|
|
|
</div>
|
|
|
-
|
|
|
- <div v-if="candidateInfo.strengths && candidateInfo.strengths.length > 0" class="border-b pb-4">
|
|
|
- <h3 class="font-semibold mb-2">优点</h3>
|
|
|
- <ul class="list-disc pl-5 text-gray-600 text-sm">
|
|
|
- <li v-for="(strength, index) in candidateInfo.strengths" :key="'strength-'+index">
|
|
|
- {{ strength }}
|
|
|
- </li>
|
|
|
- </ul>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div v-if="candidateInfo.weaknesses && candidateInfo.weaknesses.length > 0" class="border-b pb-4">
|
|
|
- <h3 class="font-semibold mb-2">需改进的地方</h3>
|
|
|
- <ul class="list-disc pl-5 text-gray-600 text-sm">
|
|
|
- <li v-for="(weakness, index) in candidateInfo.weaknesses" :key="'weakness-'+index">
|
|
|
- {{ weakness }}
|
|
|
- </li>
|
|
|
- </ul>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 修改 DUV 得分显示部分 -->
|
|
|
- <div class="border-b pb-4">
|
|
|
- <div class="flex items-center justify-between mt-4 mb-2">
|
|
|
- <span class="text-gray-600">DUV 心理测评得分</span>
|
|
|
- <span :class="getDuvScoreClass(apiData?.scoring_summary?.total_score_obtained)">
|
|
|
- {{ getSafeScoreValue(apiData?.scoring_summary?.total_score_obtained) }}
|
|
|
- <span class="ml-2 text-sm">({{ getDuvScoreLevel(apiData?.scoring_summary?.total_score_obtained) }})</span>
|
|
|
- </span>
|
|
|
- </div>
|
|
|
- <p class="text-gray-600 text-sm">
|
|
|
- {{ getDuvScoreInterpretation(apiData?.scoring_summary?.total_score_obtained) }}
|
|
|
- </p>
|
|
|
- <p class="text-sm mt-1" :class="getDuvScoreClass(apiData?.scoring_summary?.total_score_obtained)">
|
|
|
- <strong>录用建议:</strong> {{ getDuvHireRecommendation(apiData?.scoring_summary?.total_score_obtained) }}
|
|
|
- </p>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 2. DUV分析评估 -->
|
|
|
- <div class="mb-8">
|
|
|
+ <div id="image-analysis" class="mb-8 pt-4 border-t border-transparent">
|
|
|
<h2 class="text-xl font-bold mb-6">2. 图片分析评估</h2>
|
|
|
<div class="space-y-4">
|
|
|
|
|
@@ -1223,8 +1315,7 @@ const handleViewProfile = () => {
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 3. 回答记录 -->
|
|
|
- <div class="mb-8">
|
|
|
+ <div id="answer-records" class="mb-8 pt-4 border-t border-transparent">
|
|
|
<h2 class="text-xl font-bold mb-6">3. 回答记录</h2>
|
|
|
<div class="space-y-4">
|
|
|
<div v-for="(record, index) in candidateInfo.interviewRecord" :key="index" class="bg-gray-50 rounded-lg p-4">
|
|
@@ -1366,36 +1457,7 @@ const handleViewProfile = () => {
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 4. 视频记录 -->
|
|
|
- <!-- <div class="mb-8">
|
|
|
- <h2 class="text-xl font-bold mb-6">4. 视频记录</h2>
|
|
|
- <div class="space-y-8">
|
|
|
- <div v-for="(category, index) in candidateInfo.videoRecords" :key="index">
|
|
|
- <h3 class="text-lg font-semibold mb-4">{{ category.category }}</h3>
|
|
|
- <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
|
- <div v-for="(video, vIndex) in category.videos" :key="vIndex" class="bg-gray-50 rounded-lg p-4">
|
|
|
- <div class="video-container">
|
|
|
- <video
|
|
|
- class="w-full h-full object-cover"
|
|
|
- controls
|
|
|
- :src="video.url"
|
|
|
- preload="metadata"
|
|
|
- :poster="fallbackImageBase64Ref"
|
|
|
- @loadeddata="handleVideoLoaded"
|
|
|
- @error="handleVideoError"
|
|
|
- >
|
|
|
- 您的浏览器不支持视频播放。
|
|
|
- </video>
|
|
|
- </div>
|
|
|
- <p class="text-sm text-gray-600 mt-2">{{ video.description }}</p>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div> -->
|
|
|
-
|
|
|
- <!-- 其他信息 -->
|
|
|
- <div class="mb-8">
|
|
|
+ <div id="other-info" class="mb-8 pt-4 border-t border-transparent">
|
|
|
<h2 class="text-xl font-bold mb-6">4. 其他信息</h2>
|
|
|
<div class="space-y-6">
|
|
|
<!-- 验证状态列表 -->
|
|
@@ -1796,6 +1858,7 @@ const handleViewProfile = () => {
|
|
|
html, body {
|
|
|
height: 100%;
|
|
|
scroll-behavior: smooth;
|
|
|
+ overflow-y: auto !important; /* 强制允许垂直滚动 */
|
|
|
}
|
|
|
|
|
|
/* 确保主容器可以正常滚动 */
|
|
@@ -1962,4 +2025,62 @@ body {
|
|
|
padding: 12px 20px;
|
|
|
border-top: 1px solid #ebeef5;
|
|
|
}
|
|
|
+
|
|
|
+/* 添加标签样式 */
|
|
|
+:deep(.el-tabs__nav-wrap) {
|
|
|
+ background-color: white;
|
|
|
+ border-radius: 8px;
|
|
|
+ padding: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.el-tabs__item) {
|
|
|
+ color: #606266;
|
|
|
+ font-size: 14px;
|
|
|
+ padding: 0 20px;
|
|
|
+ height: 36px;
|
|
|
+ line-height: 36px;
|
|
|
+ transition: all 0.3s;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.el-tabs__item.is-active) {
|
|
|
+ color: #0066cc;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.el-tabs__active-bar) {
|
|
|
+ background-color: #0066cc;
|
|
|
+}
|
|
|
+
|
|
|
+/* 确保内容区域有足够的滚动空间 */
|
|
|
+.space-y-4 > div {
|
|
|
+ scroll-margin-top: 120px; /* 增加滚动边距,避免被固定导航遮挡 */
|
|
|
+}
|
|
|
+
|
|
|
+/* 主要章节的滚动定位调整 */
|
|
|
+#comprehensive-assessment,
|
|
|
+#image-analysis,
|
|
|
+#answer-records,
|
|
|
+#other-info {
|
|
|
+ scroll-margin-top: 120px; /* 增加滚动边距 */
|
|
|
+ padding-top: 20px; /* 添加顶部内边距,使内容更清晰可见 */
|
|
|
+ border-top: 1px solid transparent; /* 添加透明边框,帮助滚动定位 */
|
|
|
+}
|
|
|
+
|
|
|
+/* 打印时隐藏固定导航 */
|
|
|
+@media print {
|
|
|
+ .sticky-tabs {
|
|
|
+ display: none !important;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 确保固定导航不会干扰滚动 */
|
|
|
+.sticky-tabs {
|
|
|
+ position: sticky;
|
|
|
+ top: -24px;
|
|
|
+ z-index: 10;
|
|
|
+ background-color: white;
|
|
|
+ padding: 10px 0;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ /* box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); */
|
|
|
+}
|
|
|
</style>
|