dashboard/src/components/LabDrawerDetail.vue
“zhuzihan”  2d152c5e2d 教师模块
2025-07-03 15:10:49 +08:00

632 lines
14 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.

<template>
<el-drawer
v-model="drawerVisible"
direction="rtl"
size="900px"
custom-class="lab-drawer"
>
<div class="drawer-content">
<!-- 工程研究中心信息表单 - 仅在数据加载后显示 -->
<div v-if="dataLoaded" class="lab-info-form">
<div class="form-header">
<div class="basic-info">
<div class="form-row">
<div class="form-item">
<span class="label">编号:</span>
<span class="display-text">{{ labData.basicInformation.name0 }}</span>
</div>
<div class="form-item">
<span class="label">工程研究中心名称:</span>
<span class="display-text">{{ labData.basicInformation.name1 }}</span>
</div>
</div>
<div class="form-row">
<div class="form-item">
<span class="label">所属领域:</span>
<span class="display-text">{{ labData.basicInformation.name2 }}</span>
</div>
<div class="form-item">
<span class="label">所属学校:</span>
<span class="display-text">{{ labData.basicInformation.name3 }}</span>
</div>
<div class="form-item">
<span class="label">主管部门:</span>
<span class="display-text">{{ labData.basicInformation.name4 }}</span>
</div>
</div>
</div>
</div>
<!-- 工程研究中心年度信息 - 合并成一个card -->
<div class="detail-sections">
<h3 class="section-title">详细信息</h3>
<div class="year-content">
<div class="display-form">
<!-- 工程研究中心概况 -->
<div class="form-section">
<!-- 在这里实现图片中的内容 -->
<div class="display-textarea">
<!-- 遍历 labData.resultList -->
<div v-for="(categoryItem, index) in labData.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>
<span class="item-score">{{ labData.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>
</div>
</div>
</div>
</div>
<template #footer>
<div class="drawer-footer">
<button class="drawer-btn cancel-btn" @click="handleClose">关闭</button>
<!-- 确定按钮 - 已移除 -->
</div>
</template>
</el-drawer>
</template>
<script setup>
import { ref, reactive, computed, watch, nextTick, onUnmounted } from 'vue';
const props = defineProps({
visible: {
type: Boolean,
default: false
},
// dimensions 属性可以考虑移除,因为它不再被使用
dimensions: {
type: Array,
default: () => []
},
labData: { // 直接使用labData来展示信息
type: Object,
default: () => ({})
}
});
const emit = defineEmits(['update:visible']); // 移除'save'事件
// 用于visible属性的双向绑定
const drawerVisible = computed({
get: () => props.visible,
set: (val) => emit('update:visible', val)
});
// 默认工程研究中心图片占位符 (不再使用,但变量保留)
const defaultImage = `/image/实验室1.png`;
// 数据是否已加载标志
const dataLoaded = ref(false); // 控制页面内容是否显示当labData有效时设为true
// 监听props.labData变化来更新显示内容
watch(() => props.labData, (newValue) => {
if (newValue && Object.keys(newValue).length > 0) {
dataLoaded.value = true;
} else {
dataLoaded.value = false;
}
}, { immediate: true, deep: true }); // 立即执行一次watch并深度监听
// 监听抽屉可见性变化,确保在打开时正确初始化
watch(() => props.visible, (isVisible) => {
if (isVisible) {
if (props.labData && Object.keys(props.labData).length > 0) {
dataLoaded.value = true;
} else {
dataLoaded.value = false;
}
} else {
dataLoaded.value = false; // 抽屉关闭时,重置加载状态
}
});
// 计算每个分类的总分
const calculateCategoryTotal = (resultArray) => {
if (!props.labData.assessmentScore) {
return 0;
}
let totalScore = 0;
resultArray.forEach(item => {
// 使用 Number() 代替 parseInt(),更推荐用于可能包含小数的数字,
// 尽管此处分数都是整数,但更通用。如果值为 null/undefined/''Number() 会得到 0。
const score = Number(props.labData.assessmentScore[item.prop]);
if (!isNaN(score)) { // 确保是数字
totalScore += score;
}
});
return totalScore;
};
// 计算所有大项的总分
const overallTotalScore = computed(() => {
let total = 0;
if (props.labData.resultList && props.labData.assessmentScore) {
props.labData.resultList.forEach(categoryItem => {
total += calculateCategoryTotal(categoryItem.result);
});
}
return total;
});
// 处理关闭
const handleClose = () => {
drawerVisible.value = false;
dataLoaded.value = false; // 抽屉关闭时重置加载状态
};
</script>
<style>
@import './common.css';
.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>
.lab-drawer :deep(.el-drawer__header) {
margin-bottom: 0;
color: white;
background-color: #0c1633;
border-bottom: 1px solid rgba(73,134,255,0.3);
}
.lab-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;
}
/* 标签导航 */
.tab-navigation {
display: none; /* 隐藏标签导航 */
}
.tab-item {
display: none; /* 隐藏标签项 */
}
/* URL输入部分 - 已移除 */
.url-input-container {
display: none;
}
.url-input {
display: none;
}
/* 上传部分 - 已移除 */
.upload-container {
display: none;
}
.el-upload__tip {
display: none;
}
/* 手动输入提示 - 已移除 */
.manual-input-tip {
display: none;
}
/* 工程研究中心信息表单 */
.form-header {
display: flex;
margin-bottom: 30px;
background-color: #1f3266;
border-radius: 8px;
padding: 15px;
border: 1px solid rgba(73,134,255,0.3);
}
.image-section {
/* 尽管不再显示图片,但保留此样式以防万一或未来修改 */
margin-right: 20px;
display: flex;
flex-direction: column;
align-items: center;
}
.lab-image {
width: 150px;
height: 100px;
overflow: hidden;
border-radius: 4px;
margin-bottom: 10px;
}
.lab-image img {
width: 100%;
height: 100%;
object-fit: cover;
}
.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;
}
.form-item.full-width {
flex: 3;
}
.label {
display: block;
margin-bottom: 8px;
color: rgba(255,255,255,0.7);
}
/* 新增的显示文本样式 */
.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; /* 保持与input类似的高度 */
display: flex;
align-items: center;
color: white;
word-break: break-all; /* 防止长文本溢出 */
}
.display-textarea {
/* 尽管不再有直接的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; /* 保持与textarea类似的高度 */
color: white;
line-height: 1.8;
white-space: pre-wrap; /* 保留换行符和空格 */
word-break: break-all;
/* 为内部布局设置 flex */
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 {
font-size: 16px;
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; /* 标签占据大部分空间 */
color: rgba(255,255,255,0.9);
margin-right: 10px; /* 标签和分数之间的间距 */
line-height: 20px;
font-size: 16px;
}
.item-score {
font-weight: bold;
color: #4986ff; /* 分数颜色 */
flex-shrink: 0; /* 分数不收缩 */
}
/* 详细信息部分 - 样式已移除或不再需要 */
.detail-sections {
border-radius: 8px;
padding: 15px;
background-color: #1f3266;
border: 1px solid rgba(73,134,255,0.3);
}
.section-title {
/* 此样式已不再需要 */
margin: 15px 0 10px;
font-size: 16px;
color: rgba(255,255,255,0.9);
}
.section-content {
/* 此样式已不再需要 */
margin-bottom: 20px;
}
/* 雷达图部分 - 样式已移除或不再需要 */
.evaluation-chart-section {
/* 此部分已不再包含雷达图DOM可以考虑移除整个section或将其display: none */
display: none; /* 隐藏雷达图容器 */
background-color: #1f3266;
border-radius: 8px;
padding: 15px;
border: 1px solid rgba(73,134,255,0.3);
}
.radar-chart {
/* 此样式已不再需要 */
width: 100%;
height: 0px; /* 设置高度为0或display: none */
min-height: 0px;
}
/* 抽屉页脚 */
.lab-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;
}
/* 按钮样式 */
.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);
}
.confirm-btn {
display: none; /* 隐藏确定按钮 */
}
/* 滚动条样式 */
.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;
}
.sub-dimension-section {
margin-bottom: 20px;
background-color: rgba(12, 22, 51, 0.3);
border-radius: 8px;
padding: 15px;
border: 1px solid rgba(73, 134, 255, 0.3);
}
.primary-dimension-name {
font-size: 16px;
font-weight: bold;
color: #4986ff;
margin-bottom: 15px;
border-bottom: 1px solid rgba(73, 134, 255, 0.3);
padding-bottom: 8px;
}
.sub-dimensions-list {
display: flex;
flex-direction: column;
gap: 15px;
}
.sub-dimension-item {
padding: 10px;
background-color: rgba(31, 50, 102, 0.3);
border-radius: 6px;
}
.sub-dimension-name {
margin-bottom: 10px;
color: white;
font-size: 14px;
}
/* Override element-plus slider styles for dark theme */
.sub-dimension-item :deep(.el-slider__runway) {
background-color: rgba(255, 255, 255, 0.1);
}
.sub-dimension-item :deep(.el-slider__bar) {
background-color: #4986ff;
}
.sub-dimension-item :deep(.el-slider__button) {
border: 2px solid #4986ff;
background-color: white;
}
/* 年份tab样式 - 隐藏 */
.year-tabs {
display: none;
}
.year-tab {
display: none;
}
/* 年度信息展示样式 */
.year-info-display {
padding: 20px 0;
}
.info-section {
margin-bottom: 25px;
padding: 15px;
background-color: rgba(12,22,51,0.3);
border-radius: 8px;
border-left: 4px solid #4986ff;
}
.info-title {
font-size: 16px;
font-weight: 600;
color: #4986ff;
margin: 0 0 12px 0;
display: flex;
align-items: center;
}
.info-content {
line-height: 1.8;
color: rgba(255,255,255,0.9);
margin: 0;
text-align: justify;
word-break: break-all;
}
/* 统计数据网格样式 */
.stats-section {
margin-top: 20px;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 15px;
margin-top: 15px;
}
.stat-item {
background: rgba(31,50,102,0.4);
padding: 15px;
border-radius: 8px;
text-align: center;
border: 1px solid rgba(73,134,255,0.3);
}
.stat-label {
color: rgba(255,255,255,0.7);
font-size: 12px;
margin-bottom: 8px;
}
.stat-value {
color: #4986ff;
font-size: 18px;
font-weight: bold;
}
/* 编辑表单样式 */
.edit-form {
padding: 20px 0;
}
.form-section {
margin-bottom: 20px;
}
.form-section-title {
font-size: 14px;
font-weight: 600;
color: #4986ff;
margin: 0 0 10px 0;
}
/* 新增:总分显示样式 */
.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; /* 突出显示总分 */
}
</style><style>
.el-upload--text{
width: 100%;
}</style>