dashboard/src/components/LabDrawerDetail.vue

632 lines
14 KiB
Vue
Raw Normal View History

2025-06-09 14:59:40 +08:00
<template>
<el-drawer
v-model="drawerVisible"
direction="rtl"
size="900px"
custom-class="lab-drawer"
>
<div class="drawer-content">
<!-- 工程研究中心信息表单 - 仅在数据加载后显示 -->
2025-06-27 15:54:55 +08:00
<div v-if="dataLoaded" class="lab-info-form">
2025-06-09 14:59:40 +08:00
<div class="form-header">
<div class="basic-info">
<div class="form-row">
<div class="form-item">
<span class="label">编号:</span>
2025-06-27 15:54:55 +08:00
<span class="display-text">{{ labData.basicInformation.name0 }}</span>
2025-06-09 14:59:40 +08:00
</div>
<div class="form-item">
<span class="label">工程研究中心名称:</span>
2025-06-27 15:54:55 +08:00
<span class="display-text">{{ labData.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-06-27 15:54:55 +08:00
<span class="display-text">{{ labData.basicInformation.name2 }}</span>
2025-06-09 14:59:40 +08:00
</div>
<div class="form-item">
<span class="label">所属学校:</span>
2025-06-27 15:54:55 +08:00
<span class="display-text">{{ labData.basicInformation.name3 }}</span>
2025-06-09 14:59:40 +08:00
</div>
<div class="form-item">
<span class="label">主管部门:</span>
2025-06-27 15:54:55 +08:00
<span class="display-text">{{ labData.basicInformation.name4 }}</span>
2025-06-09 14:59:40 +08:00
</div>
</div>
</div>
</div>
<!-- 工程研究中心年度信息 - 合并成一个card -->
<div class="detail-sections">
2025-06-27 15:54:55 +08:00
<h3 class="section-title">详细信息</h3>
<div class="year-content">
<div class="display-form">
2025-06-09 14:59:40 +08:00
<!-- 工程研究中心概况 -->
<div class="form-section">
2025-06-27 15:54:55 +08:00
<!-- 在这里实现图片中的内容 -->
<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>
2025-06-09 14:59:40 +08:00
</div>
</div>
2025-06-27 15:54:55 +08:00
<!-- 新增总分显示 -->
<div class="overall-score-section">
<span class="overall-score-label">总分:</span>
<span class="overall-score-value">{{ overallTotalScore }}</span>
2025-06-09 14:59:40 +08:00
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<template #footer>
<div class="drawer-footer">
2025-06-27 15:54:55 +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-06-27 15:54:55 +08:00
import { ref, reactive, computed, watch, nextTick, onUnmounted } from 'vue';
2025-06-09 14:59:40 +08:00
const props = defineProps({
visible: {
type: Boolean,
default: false
},
2025-06-27 15:54:55 +08:00
// dimensions 属性可以考虑移除,因为它不再被使用
2025-06-09 14:59:40 +08:00
dimensions: {
type: Array,
default: () => []
},
2025-06-27 15:54:55 +08:00
labData: { // 直接使用labData来展示信息
2025-06-09 14:59:40 +08:00
type: Object,
default: () => ({})
}
});
2025-06-27 15:54:55 +08:00
const emit = defineEmits(['update:visible']); // 移除'save'事件
2025-06-09 14:59:40 +08:00
// 用于visible属性的双向绑定
const drawerVisible = computed({
get: () => props.visible,
set: (val) => emit('update:visible', val)
});
2025-06-27 15:54:55 +08:00
// 默认工程研究中心图片占位符 (不再使用,但变量保留)
2025-06-09 14:59:40 +08:00
const defaultImage = `/image/实验室1.png`;
// 数据是否已加载标志
2025-06-27 15:54:55 +08:00
const dataLoaded = ref(false); // 控制页面内容是否显示当labData有效时设为true
2025-06-09 14:59:40 +08:00
2025-06-27 15:54:55 +08:00
// 监听props.labData变化来更新显示内容
2025-06-09 14:59:40 +08:00
watch(() => props.labData, (newValue) => {
2025-06-27 15:54:55 +08:00
if (newValue && Object.keys(newValue).length > 0) {
dataLoaded.value = true;
} else {
dataLoaded.value = false;
2025-06-09 14:59:40 +08:00
}
2025-06-27 15:54:55 +08:00
}, { immediate: true, deep: true }); // 立即执行一次watch并深度监听
2025-06-09 14:59:40 +08:00
2025-06-27 15:54:55 +08:00
// 监听抽屉可见性变化,确保在打开时正确初始化
2025-06-09 14:59:40 +08:00
watch(() => props.visible, (isVisible) => {
if (isVisible) {
2025-06-27 15:54:55 +08:00
if (props.labData && Object.keys(props.labData).length > 0) {
2025-06-09 14:59:40 +08:00
dataLoaded.value = true;
2025-06-27 15:54:55 +08:00
} else {
dataLoaded.value = false;
2025-06-09 14:59:40 +08:00
}
2025-06-27 15:54:55 +08:00
} else {
dataLoaded.value = false; // 抽屉关闭时,重置加载状态
2025-06-09 14:59:40 +08:00
}
});
2025-06-27 15:54:55 +08:00
// 计算每个分类的总分
const calculateCategoryTotal = (resultArray) => {
if (!props.labData.assessmentScore) {
return 0;
2025-06-09 14:59:40 +08:00
}
2025-06-27 15:54:55 +08:00
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;
2025-06-09 14:59:40 +08:00
}
});
2025-06-27 15:54:55 +08:00
return totalScore;
2025-06-09 14:59:40 +08:00
};
2025-06-27 15:54:55 +08:00
// 计算所有大项的总分
const overallTotalScore = computed(() => {
let total = 0;
if (props.labData.resultList && props.labData.assessmentScore) {
props.labData.resultList.forEach(categoryItem => {
total += calculateCategoryTotal(categoryItem.result);
2025-06-09 14:59:40 +08:00
});
}
2025-06-27 15:54:55 +08:00
return total;
});
2025-06-09 14:59:40 +08:00
// 处理关闭
const handleClose = () => {
drawerVisible.value = false;
2025-06-27 15:54:55 +08:00
dataLoaded.value = false; // 抽屉关闭时重置加载状态
2025-06-09 14:59:40 +08:00
};
</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 {
2025-06-27 15:54:55 +08:00
display: none; /* 隐藏标签导航 */
2025-06-09 14:59:40 +08:00
}
.tab-item {
2025-06-27 15:54:55 +08:00
display: none; /* 隐藏标签项 */
2025-06-09 14:59:40 +08:00
}
2025-06-27 15:54:55 +08:00
/* URL输入部分 - 已移除 */
2025-06-09 14:59:40 +08:00
.url-input-container {
2025-06-27 15:54:55 +08:00
display: none;
2025-06-09 14:59:40 +08:00
}
.url-input {
2025-06-27 15:54:55 +08:00
display: none;
2025-06-09 14:59:40 +08:00
}
2025-06-27 15:54:55 +08:00
/* 上传部分 - 已移除 */
2025-06-09 14:59:40 +08:00
.upload-container {
2025-06-27 15:54:55 +08:00
display: none;
2025-06-09 14:59:40 +08:00
}
.el-upload__tip {
2025-06-27 15:54:55 +08:00
display: none;
2025-06-09 14:59:40 +08:00
}
2025-06-27 15:54:55 +08:00
/* 手动输入提示 - 已移除 */
2025-06-09 14:59:40 +08:00
.manual-input-tip {
2025-06-27 15:54:55 +08:00
display: none;
2025-06-09 14:59:40 +08:00
}
/* 工程研究中心信息表单 */
.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 {
2025-06-27 15:54:55 +08:00
/* 尽管不再显示图片,但保留此样式以防万一或未来修改 */
2025-06-09 14:59:40 +08:00
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);
}
2025-06-27 15:54:55 +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; /* 保持与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; /* 分数不收缩 */
}
/* 详细信息部分 - 样式已移除或不再需要 */
2025-06-09 14:59:40 +08:00
.detail-sections {
border-radius: 8px;
padding: 15px;
2025-06-27 15:54:55 +08:00
background-color: #1f3266;
2025-06-09 14:59:40 +08:00
border: 1px solid rgba(73,134,255,0.3);
}
.section-title {
2025-06-27 15:54:55 +08:00
/* 此样式已不再需要 */
2025-06-09 14:59:40 +08:00
margin: 15px 0 10px;
font-size: 16px;
color: rgba(255,255,255,0.9);
}
.section-content {
2025-06-27 15:54:55 +08:00
/* 此样式已不再需要 */
2025-06-09 14:59:40 +08:00
margin-bottom: 20px;
}
2025-06-27 15:54:55 +08:00
/* 雷达图部分 - 样式已移除或不再需要 */
2025-06-09 14:59:40 +08:00
.evaluation-chart-section {
2025-06-27 15:54:55 +08:00
/* 此部分已不再包含雷达图DOM可以考虑移除整个section或将其display: none */
display: none; /* 隐藏雷达图容器 */
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);
}
.radar-chart {
2025-06-27 15:54:55 +08:00
/* 此样式已不再需要 */
2025-06-09 14:59:40 +08:00
width: 100%;
2025-06-27 15:54:55 +08:00
height: 0px; /* 设置高度为0或display: none */
min-height: 0px;
2025-06-09 14:59:40 +08:00
}
/* 抽屉页脚 */
.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 {
2025-06-27 15:54:55 +08:00
display: none; /* 隐藏确定按钮 */
2025-06-09 14:59:40 +08:00
}
/* 滚动条样式 */
.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;
}
2025-06-27 15:54:55 +08:00
/* 年份tab样式 - 隐藏 */
2025-06-09 14:59:40 +08:00
.year-tabs {
2025-06-27 15:54:55 +08:00
display: none;
2025-06-09 14:59:40 +08:00
}
.year-tab {
2025-06-27 15:54:55 +08:00
display: none;
2025-06-09 14:59:40 +08:00
}
/* 年度信息展示样式 */
.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;
}
2025-06-27 15:54:55 +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; /* 突出显示总分 */
}
2025-06-09 14:59:40 +08:00
</style><style>
.el-upload--text{
width: 100%;
2025-06-27 15:54:55 +08:00
}</style>