dashboard/src/components/TalentDrawerDetail.vue

417 lines
9.9 KiB
Vue
Raw Normal View History

2025-06-09 14:59:40 +08:00
<template>
<el-drawer
v-model="drawerVisible"
2025-07-03 15:10:49 +08:00
title=""
2025-06-09 14:59:40 +08:00
direction="rtl"
size="900px"
:before-close="handleClose"
custom-class="talent-drawer"
>
<div class="drawer-content">
<!-- 个人信息表单 - 仅在数据加载后显示 -->
2025-07-03 15:10:49 +08:00
<div v-if="teacherData && teacherData.basicInformation" class="personal-info-form">
2025-06-09 14:59:40 +08:00
<div class="form-header">
<div class="photo-section">
<div class="teacher-photo">
2025-07-03 15:10:49 +08:00
<!-- 使用 teacherData.basicInformation.name7 作为图片源 -->
<img :src="teacherData.basicInformation.name7" alt="教师照片" />
2025-06-09 14:59:40 +08:00
</div>
</div>
<div class="basic-info">
<div class="form-row">
<div class="form-item">
<span class="label">姓名:</span>
2025-07-03 15:10:49 +08:00
<span class="display-text">{{ teacherData.basicInformation.name0 }}</span>
2025-06-09 14:59:40 +08:00
</div>
<div class="form-item">
<span class="label">性别:</span>
2025-07-03 15:10:49 +08:00
<span class="display-text">{{ teacherData.basicInformation.name1 }}</span>
2025-06-09 14:59:40 +08:00
</div>
</div>
<div class="form-row">
<div class="form-item">
<span class="label">职称:</span>
2025-07-03 15:10:49 +08:00
<span class="display-text">{{ teacherData.basicInformation.name2 }}</span>
2025-06-09 14:59:40 +08:00
</div>
<div class="form-item">
<span class="label">职务:</span>
2025-07-03 15:10:49 +08:00
<span class="display-text">{{ teacherData.basicInformation.name3 }}</span>
2025-06-09 14:59:40 +08:00
</div>
<div class="form-item">
2025-07-03 15:10:49 +08:00
<span class="label">所属院校:</span>
<span class="display-text">{{ teacherData.basicInformation.name4 }}</span>
2025-06-09 14:59:40 +08:00
</div>
<div class="form-item">
2025-07-03 15:10:49 +08:00
<span class="label">最高学历:</span>
<span class="display-text">{{ teacherData.basicInformation.name5 }}</span>
2025-06-09 14:59:40 +08:00
</div>
<div class="form-item">
<span class="label">学科方向:</span>
2025-07-03 15:10:49 +08:00
<span class="display-text">{{ teacherData.basicInformation.name6 }}</span>
2025-06-09 14:59:40 +08:00
</div>
</div>
</div>
</div>
2025-07-03 15:10:49 +08:00
<!-- 详细信息 - 工程研究中心年度信息 - 合并成一个card -->
2025-06-09 14:59:40 +08:00
<div class="detail-sections">
2025-07-03 15:10:49 +08:00
<h3 class="section-title">详细信息</h3>
<div class="year-content">
<div class="display-form">
<!-- 工程研究中心概况 -->
<div class="form-section">
<div class="display-textarea">
<!-- 遍历 teacherData.resultList -->
<div v-for="(categoryItem, index) in teacherData.resultList" :key="index" class="category-section">
<h4 class="category-title">
{{ categoryItem.category }} (总分: {{ calculateCategoryTotal(categoryItem.result) }})
</h4>
<div class="category-content">
<div v-for="(item, itemIndex) in categoryItem.result" :key="itemIndex" class="category-item">
<span class="item-label">{{ item.label }}:</span>
<!-- 使用 teacherData.assessmentScore[item.prop] 来显示分数如果不存在则显示 '0' -->
<span class="item-score">{{ teacherData.assessmentScore[item.prop] || '0' }}</span>
</div>
</div>
</div>
</div>
<!-- 总分显示 -->
<div class="overall-score-section">
<span class="overall-score-label">总分:</span>
<span class="overall-score-value">{{ overallTotalScore }}</span>
</div>
</div>
</div>
2025-06-09 14:59:40 +08:00
</div>
</div>
2025-07-03 15:10:49 +08:00
</div>
<!-- 如果 teacherData 未加载可以显示一个加载提示或者空状态 -->
<div v-else class="loading-placeholder">
正在加载人才数据...
2025-06-09 14:59:40 +08:00
</div>
</div>
<template #footer>
<div class="drawer-footer">
2025-07-03 15:10:49 +08:00
<button class="drawer-btn cancel-btn" @click="handleClose">关闭</button>
2025-06-09 14:59:40 +08:00
</div>
</template>
</el-drawer>
</template>
<script setup>
2025-07-03 15:10:49 +08:00
import { ref, computed } from 'vue';
2025-06-09 14:59:40 +08:00
const props = defineProps({
visible: {
type: Boolean,
default: false
},
teacherData: {
type: Object,
default: () => ({})
2025-07-03 15:10:49 +08:00
},
2025-06-09 14:59:40 +08:00
});
2025-07-03 15:10:49 +08:00
const emit = defineEmits(['update:visible']);
2025-06-09 14:59:40 +08:00
// 用于visible属性的双向绑定
const drawerVisible = computed({
get: () => props.visible,
set: (val) => emit('update:visible', val)
});
2025-07-03 15:10:49 +08:00
// 计算每个分类的总分
const calculateCategoryTotal = (resultArray) => {
if (!props.teacherData.assessmentScore) {
return 0;
2025-06-09 14:59:40 +08:00
}
2025-07-03 15:10:49 +08:00
let totalScore = 0;
resultArray.forEach(item => {
const score = Number(props.teacherData.assessmentScore[item.prop]);
if (!isNaN(score)) {
totalScore += score;
2025-06-09 14:59:40 +08:00
}
});
2025-07-03 15:10:49 +08:00
return totalScore;
2025-06-09 14:59:40 +08:00
};
2025-07-03 15:10:49 +08:00
// 计算所有大项的总分
const overallTotalScore = computed(() => {
let total = 0;
if (props.teacherData.resultList && props.teacherData.assessmentScore) {
props.teacherData.resultList.forEach(categoryItem => {
total += calculateCategoryTotal(categoryItem.result);
2025-06-09 14:59:40 +08:00
});
}
2025-07-03 15:10:49 +08:00
return total;
});
2025-06-09 14:59:40 +08:00
// 处理关闭
const handleClose = () => {
drawerVisible.value = false;
};
</script>
<style>
2025-07-03 15:10:49 +08:00
/* 移除 common.css 导入,如果其中内容不再需要 */
2025-06-09 14:59:40 +08:00
.el-drawer{
border-left: 1px solid #4986ff;
}
.el-drawer__body{
padding: 0px !important;
}
.el-drawer__header{
background-color: #0c1633 !important;
margin-bottom:0px !important;
}
.el-drawer__footer{
background-color: #0c1633 !important;
}
</style>
<style scoped>
.talent-drawer :deep(.el-drawer__header) {
margin-bottom: 0;
color: white;
background-color: #0c1633;
border-bottom: 1px solid rgba(73,134,255,0.3);
}
.talent-drawer :deep(.el-drawer__body) {
padding: 0;
overflow: hidden;
background-color: #0c1633;
}
.drawer-content {
padding: 20px;
color: white;
height: 100%;
overflow-y: auto;
background-color: #0c1633;
}
/* 个人信息表单 */
.form-header {
display: flex;
margin-bottom: 30px;
background-color: #1f3266;
border-radius: 8px;
padding: 15px;
border: 1px solid rgba(73,134,255,0.3);
}
.photo-section {
margin-right: 20px;
display: flex;
flex-direction: column;
align-items: center;
}
2025-07-03 15:10:49 +08:00
.teacher-photo {
width: 120px; /* 示例宽度 */
height: 120px; /* 示例高度 */
overflow: hidden;
border: 2px solid #4986ff; /* 边框 */
display: flex;
justify-content: center;
align-items: center;
flex-shrink: 0; /* 防止缩小 */
}
.teacher-photo img {
width: 100%;
height: 100%;
object-fit: cover; /* 保持图片比例,填充容器 */
}
2025-06-09 14:59:40 +08:00
.basic-info {
flex: 1;
}
.form-row {
display: flex;
margin-bottom: 15px;
}
.form-item {
flex: 1;
margin-right: 15px;
display: flex;
flex-direction: column;
}
.form-item:last-child {
margin-right: 0;
}
.label {
display: block;
margin-bottom: 8px;
color: rgba(255,255,255,0.7);
}
2025-07-03 15:10:49 +08:00
.display-text {
background-color: rgba(255,255,255,0.1);
box-shadow: 0 0 0 1px rgba(73,134,255,0.3) inset;
padding: 9px 15px;
border-radius: 4px;
min-height: 32px;
display: flex;
align-items: center;
color: white;
word-break: break-all;
2025-06-09 14:59:40 +08:00
}
2025-07-03 15:10:49 +08:00
.display-textarea {
background-color: rgba(255,255,255,0.1);
box-shadow: 0 0 0 1px rgba(73,134,255,0.3) inset;
padding: 9px 15px;
border-radius: 4px;
min-height: 100px;
color: white;
line-height: 1.8;
white-space: pre-wrap;
word-break: break-all;
display: flex;
flex-direction: column;
gap: 20px;
}
.category-section {
padding-bottom: 15px;
border-bottom: 1px solid rgba(73,134,255,0.2);
}
.category-section:last-child {
border-bottom: none;
padding-bottom: 0;
}
.category-title {
2025-06-09 14:59:40 +08:00
font-size: 16px;
2025-07-03 15:10:49 +08:00
font-weight: bold;
color: #4986ff;
margin-top: 0;
margin-bottom: 15px;
}
.category-content {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 15px 30px;
}
.category-item {
display: flex;
justify-content: space-between;
align-items: baseline;
word-break: break-all;
}
.item-label {
flex: 1;
2025-06-09 14:59:40 +08:00
color: rgba(255,255,255,0.9);
2025-07-03 15:10:49 +08:00
margin-right: 10px;
line-height: 20px;
font-size: 16px;
2025-06-09 14:59:40 +08:00
}
2025-07-03 15:10:49 +08:00
.item-score {
font-weight: bold;
color: #4986ff;
flex-shrink: 0;
2025-06-09 14:59:40 +08:00
}
2025-07-03 15:10:49 +08:00
/* 详细信息部分 */
.detail-sections {
2025-06-09 14:59:40 +08:00
background-color: #1f3266;
border-radius: 8px;
padding: 15px;
border: 1px solid rgba(73,134,255,0.3);
}
2025-07-03 15:10:49 +08:00
.section-title {
margin: 15px 0 10px;
font-size: 16px;
color: rgba(255,255,255,0.9);
2025-06-09 14:59:40 +08:00
}
/* 抽屉页脚 */
.talent-drawer :deep(.el-drawer__footer) {
border-top: 1px solid rgba(73,134,255,0.3);
padding: 10px 20px;
background-color: #0c1633;
}
.drawer-footer {
display: flex;
justify-content: flex-end;
}
2025-07-03 15:10:49 +08:00
/* 按钮样式 */
2025-06-09 14:59:40 +08:00
.drawer-btn {
padding: 8px 15px;
border-radius: 10px;
font-size: 14px;
font-family: PingFangSC-regular;
cursor: pointer;
margin-left: 10px;
}
.cancel-btn {
background-color: transparent;
color: rgba(255,255,255,0.8);
border: 1px solid rgba(73,134,255,0.5);
}
/* 滚动条样式 */
.drawer-content::-webkit-scrollbar {
width: 6px;
}
.drawer-content::-webkit-scrollbar-track {
background: transparent;
}
.drawer-content::-webkit-scrollbar-thumb {
background-color: #4986ff;
border-radius: 10px;
border: none;
}
2025-07-03 15:10:49 +08:00
/* 新增:总分显示样式 */
.overall-score-section {
margin-top: 20px;
padding: 15px;
background-color: rgba(12, 22, 51, 0.3);
border-radius: 8px;
border: 1px solid rgba(73, 134, 255, 0.3);
display: flex;
justify-content: flex-end;
align-items: center;
font-size: 18px;
font-weight: bold;
color: #4986ff;
}
.overall-score-label {
margin-right: 10px;
color: rgba(255,255,255,0.9);
}
.overall-score-value {
color: #4986ff;
}
.loading-placeholder {
color: rgba(255,255,255,0.7);
text-align: center;
padding: 50px;
font-size: 18px;
}
2025-06-09 14:59:40 +08:00
</style>