yangg 1 mesiac pred
rodič
commit
81d564be45
1 zmenil súbory, kde vykonal 223 pridanie a 102 odobranie
  1. 223 102
      src/views/JobApplication/report/index.vue

+ 223 - 102
src/views/JobApplication/report/index.vue

@@ -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>