提交
This commit is contained in:
@ -5,10 +5,6 @@
|
||||
"ComputedRef": true,
|
||||
"DirectiveBinding": true,
|
||||
"EffectScope": true,
|
||||
"ElLoading": true,
|
||||
"ElMessage": true,
|
||||
"ElMessageBox": true,
|
||||
"ElNotification": true,
|
||||
"ExtractDefaultPropTypes": true,
|
||||
"ExtractPropTypes": true,
|
||||
"ExtractPublicPropTypes": true,
|
||||
@ -318,6 +314,10 @@
|
||||
"watchThrottled": true,
|
||||
"watchTriggerable": true,
|
||||
"watchWithFilter": true,
|
||||
"whenever": true
|
||||
"whenever": true,
|
||||
"ElMessage": true,
|
||||
"ElLoading": true,
|
||||
"ElMessageBox": true,
|
||||
"ElNotification": true
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ export const getOption = (xData: any, yData: any) => {
|
||||
{
|
||||
// show: true,
|
||||
start: 0,
|
||||
end: 30,
|
||||
end: 100,
|
||||
bottom: 2, // 下滑块距离x轴底部的距离
|
||||
height: 23
|
||||
},
|
||||
@ -177,7 +177,7 @@ export const getOption2 = (data: any) => {
|
||||
// show: true,
|
||||
|
||||
start: 0,
|
||||
end: 30,
|
||||
end: 100,
|
||||
bottom: 2, // 下滑块距离x轴底部的距离
|
||||
height: 23
|
||||
},
|
||||
@ -322,7 +322,7 @@ export const getLineOption = (lineData: any) => {
|
||||
{
|
||||
// show: true,
|
||||
start: 0,
|
||||
end: 30,
|
||||
end: 100,
|
||||
bottom: 2, // 下滑块距离x轴底部的距离
|
||||
height: 23
|
||||
},
|
||||
@ -674,7 +674,7 @@ export const getBarOptions = (data: any) => {
|
||||
{
|
||||
// show: true,
|
||||
start: 0,
|
||||
end: 30,
|
||||
end: 100,
|
||||
bottom: 2, // 下滑块距离x轴底部的距离
|
||||
height: 23
|
||||
},
|
||||
|
||||
@ -5,28 +5,38 @@
|
||||
<div class="header">
|
||||
<img src="@/assets/large/right1.png" style="width: 17px; height: 18px" alt="" />
|
||||
<span class="title">告警信息中心</span>
|
||||
<!-- <el-badge :value="unhandledCount" class="unhandled-badge" type="danger"> {{ unhandledCount }}条未处理 </el-badge> -->
|
||||
<span class="jgao">{{ alarmData.length }}条信息未处理</span>
|
||||
</div>
|
||||
<!-- 告警卡片列表(可循环渲染,这里演示单条) -->
|
||||
<!-- 告警卡片列表 -->
|
||||
<div class="alarm_list">
|
||||
<el-card class="alarm-card" shadow="hover" v-for="(item, index) in alarmData" :key="index">
|
||||
<div class="alarm-card" v-for="(item, index) in alarmData" :key="index">
|
||||
<div class="card-header">
|
||||
<img src="@/assets/large/right2.png" style="width: 15px; height: 15px" alt="" />
|
||||
<span class="card-title">{{ item.alarmMsg }}</span>
|
||||
<span class="time">{{ formatDate(item.alarmBeginTime) }}</span>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
{{ item.advice }}
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<el-tag type="danger" size="small">紧急</el-tag>
|
||||
<el-tag type="danger" size="small">处理</el-tag>
|
||||
</div>
|
||||
</el-card>
|
||||
<div class="card-content">
|
||||
<!-- 文本容器:控制3行溢出 -->
|
||||
<div class="text-container">
|
||||
{{ item.advice }}
|
||||
</div>
|
||||
<!-- 查看更多按钮:右侧显示 -->
|
||||
<div class="read-more" @click="open(item)">查看更多</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detailBox" :class="{ 'show': newDetail }">
|
||||
<div class="boxContent" v-html="newDetail?.advice"></div>
|
||||
<!-- 假设 item 有 content 字段,根据实际调整 -->
|
||||
<div class="close" @click="newDetail = null">
|
||||
<CircleClose style="width: 1.2em; height: 1.2em" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="overview">
|
||||
<div class="left_title">
|
||||
<div style="display: flex; align-items: center">
|
||||
@ -73,7 +83,7 @@
|
||||
<span
|
||||
class="progress-percent"
|
||||
:class="{
|
||||
green1: item.rate >= 99, // 可根据需求调整颜色规则
|
||||
green1: item.rate >= 99,
|
||||
orange1: item.rate < 99 && item.rate >= 90
|
||||
}"
|
||||
>{{ item.rate }}%</span
|
||||
@ -84,7 +94,7 @@
|
||||
class="progress-fg"
|
||||
:style="{ width: item.rate + '%' }"
|
||||
:class="{
|
||||
green: item.rate >= 99, // 可根据需求调整颜色规则
|
||||
green: item.rate >= 99,
|
||||
orange: item.rate < 99 && item.rate >= 90
|
||||
}"
|
||||
></div>
|
||||
@ -93,7 +103,6 @@
|
||||
</div>
|
||||
<div class="container_item_two">
|
||||
<div>正常{{ item.normal }}台</div>
|
||||
|
||||
<div>异常{{ item.abnormal }}台</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -103,15 +112,15 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { ref, nextTick, onUnmounted } from 'vue';
|
||||
import { getAlarmListOverview } from '@/api/large';
|
||||
import { formatDate } from '@/utils/index';
|
||||
|
||||
const alarmData: any = ref({});
|
||||
const alarmData = ref<any[]>([]);
|
||||
const deviceStats = ref([
|
||||
{
|
||||
name: '光伏组件',
|
||||
icon: '../../../assets/large/right5.png', // 示例图标
|
||||
icon: '../../../assets/large/right5.png',
|
||||
total: '25,680',
|
||||
unit: '块',
|
||||
rate: 99.2,
|
||||
@ -155,13 +164,85 @@ const deviceStats = ref([
|
||||
abnormal: 12
|
||||
}
|
||||
]);
|
||||
|
||||
// 存储所有绑定的事件处理函数,用于卸载时解绑
|
||||
const eventHandlers: Array<() => void> = [];
|
||||
|
||||
// 处理“查看更多/收起”逻辑
|
||||
const handleReadMore = async () => {
|
||||
await nextTick();
|
||||
|
||||
const textContainers: any = document.querySelectorAll('.alarm-card .text-container');
|
||||
const readMoreBtns: any = document.querySelectorAll('.alarm-card .read-more');
|
||||
|
||||
// 清空之前的事件绑定(避免重复绑定)
|
||||
eventHandlers.forEach((handler) => handler());
|
||||
eventHandlers.length = 0;
|
||||
|
||||
textContainers.forEach((textContainer, index) => {
|
||||
const btn = readMoreBtns[index] as HTMLDivElement;
|
||||
if (!btn) return;
|
||||
|
||||
// 关键修改:判断文本是否超过3行(scrollHeight > clientHeight 表示溢出)
|
||||
const isOverflow = textContainer.scrollHeight > textContainer.clientHeight;
|
||||
btn.style.display = isOverflow ? 'inline-block' : 'none';
|
||||
|
||||
// 定义点击事件处理函数
|
||||
// const toggleExpand = () => {
|
||||
// const isExpanded = textContainer.style.webkitLineClamp === 'none';
|
||||
// if (isExpanded) {
|
||||
// // 收起:恢复3行限制
|
||||
// textContainer.style.webkitLineClamp = '3';
|
||||
// btn.textContent = '查看更多';
|
||||
// } else {
|
||||
// // 展开:取消行数限制
|
||||
// textContainer.style.webkitLineClamp = 'none';
|
||||
// btn.textContent = '收起';
|
||||
// }
|
||||
// };
|
||||
|
||||
// 绑定点击事件并存储,用于后续解绑
|
||||
// btn.addEventListener('click', toggleExpand);
|
||||
// eventHandlers.push(() => {
|
||||
// btn.removeEventListener('click', toggleExpand);
|
||||
// });
|
||||
});
|
||||
};
|
||||
|
||||
// 接口请求:获取告警数据后执行处理逻辑
|
||||
const getAlarm = () => {
|
||||
getAlarmListOverview().then((res) => {
|
||||
console.log(res);
|
||||
alarmData.value = res.data;
|
||||
handleReadMore(); // 数据渲染后执行文本溢出处理
|
||||
});
|
||||
};
|
||||
// 初始化调用接口
|
||||
getAlarm();
|
||||
// 定义 item 类型(替换 any,提升类型安全性)
|
||||
interface ItemType {
|
||||
id: string | number;
|
||||
advice: string; // 存储富文本内容的字段,根据实际数据结构调整
|
||||
// 其他字段...
|
||||
}
|
||||
const newDetail = ref(null);
|
||||
|
||||
// 假设 item 是当前列表项(实际可能来自 v-for 循环)
|
||||
const item = ref<ItemType>({
|
||||
id: 1,
|
||||
advice: '<p>这是要显示的详情内容...</p>' // 示例富文本内容
|
||||
});
|
||||
|
||||
// 切换展开/隐藏逻辑
|
||||
const open = (targetItem: ItemType) => {
|
||||
// 如果当前展开的就是目标项 → 隐藏;否则 → 展开目标项
|
||||
newDetail.value = newDetail.value === targetItem ? null : targetItem;
|
||||
console.log(newDetail.value);
|
||||
};
|
||||
// 组件卸载时解绑所有事件(避免内存泄漏)
|
||||
onUnmounted(() => {
|
||||
eventHandlers.forEach((handler) => handler());
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@ -171,10 +252,9 @@ getAlarm();
|
||||
}
|
||||
|
||||
.alarm-container {
|
||||
border: 1px solid #1e2b3d; /* 深色背景模拟,可替换成项目背景 */
|
||||
border: 1px solid #1e2b3d;
|
||||
border-radius: 8px;
|
||||
color: #fff;
|
||||
// box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
@ -203,8 +283,8 @@ getAlarm();
|
||||
.alarm_list {
|
||||
width: 100%;
|
||||
padding: 5px 0;
|
||||
height: 14vh;
|
||||
overflow-y: auto; /* 垂直方向超出时显示滚动条 */
|
||||
height: 17vh;
|
||||
// overflow-y: auto; /* 垂直方向超出时显示滚动条 */
|
||||
}
|
||||
// 滚动条优化
|
||||
.alarm_list::-webkit-scrollbar {
|
||||
@ -220,18 +300,19 @@ getAlarm();
|
||||
}
|
||||
/* 告警卡片 */
|
||||
.alarm-card {
|
||||
height: 100%;
|
||||
background: rgba(12, 30, 53, 0.3);
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #f56c6c;
|
||||
margin-top: 10px;
|
||||
padding: 5px;
|
||||
margin-bottom: 8px; /* 增加卡片间距,避免重叠 */
|
||||
}
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
// justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.card-title {
|
||||
font-size: 16px;
|
||||
@ -244,16 +325,49 @@ getAlarm();
|
||||
color: #909399;
|
||||
margin-left: auto; /* 右对齐 */
|
||||
}
|
||||
/* 关键修改:卡片内容容器(承载文本和按钮) */
|
||||
.card-content {
|
||||
font-size: 13px;
|
||||
color: #dcdfe6;
|
||||
margin-bottom: 12px;
|
||||
// margin-bottom: 12px;
|
||||
line-height: 1.6;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
line-height: 1.5;
|
||||
// padding-right: 70px; /* 给右侧按钮预留空间,避免超出卡片 */
|
||||
min-height: 4.5em; /* 3行文本高度(1.5line-height * 3),确保按钮位置稳定 */
|
||||
}
|
||||
|
||||
/* 关键修改:文本容器(限制3行) */
|
||||
.text-container {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3; /* 限制显示3行 */
|
||||
overflow: hidden;
|
||||
word-break: break-all;
|
||||
padding-bottom: 2px; /* 避免文本底部被按钮遮挡 */
|
||||
}
|
||||
|
||||
/* 关键修改:查看更多按钮(右侧显示+深色适配) */
|
||||
.read-more {
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: -20px;
|
||||
/* 渐变遮罩改为卡片背景色,避免白色块 */
|
||||
background: linear-gradient(to right, transparent, rgba(12, 30, 53, 0.3) 60%);
|
||||
padding-left: 15px; /* 增加遮罩宽度,避免文字与按钮重叠 */
|
||||
color: #1677ff;
|
||||
cursor: pointer;
|
||||
z-index: 1; /* 确保按钮在文本上方 */
|
||||
white-space: nowrap; /* 按钮文字不换行 */
|
||||
font-size: 13px; /* 与文本字号一致 */
|
||||
}
|
||||
.card-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.left_title {
|
||||
width: 100%;
|
||||
@ -290,7 +404,7 @@ img {
|
||||
}
|
||||
.overview {
|
||||
width: 100%;
|
||||
height: 28vh;
|
||||
height: 25vh;
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #1e2b3d;
|
||||
@ -301,7 +415,7 @@ img {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
line-height: 30px;
|
||||
overflow-y: auto; /* 垂直方向超出时显示滚动条 */
|
||||
overflow-y: auto;
|
||||
}
|
||||
// 滚动条优化
|
||||
.overview_content::-webkit-scrollbar {
|
||||
@ -325,15 +439,14 @@ img {
|
||||
border-radius: 10px;
|
||||
|
||||
.stats-container {
|
||||
width: 100%; /* 可根据实际场景调整宽度 */
|
||||
width: 100%;
|
||||
height: 87%;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto; /* 垂直方向超出时显示滚动条 */
|
||||
overflow-y: auto;
|
||||
.container_item {
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
@ -359,13 +472,10 @@ img {
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding-left: 10px;
|
||||
// align-items: center;
|
||||
}
|
||||
}
|
||||
/* 右侧区域:进度条 + 数据 */
|
||||
.card-right {
|
||||
display: flex;
|
||||
|
||||
margin-left: 10px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
@ -381,7 +491,7 @@ img {
|
||||
font-weight: bold;
|
||||
}
|
||||
.abnormal {
|
||||
color: #ff9900; /* 异常数据颜色 */
|
||||
color: #ff9900;
|
||||
}
|
||||
.progress-bg {
|
||||
height: 6px;
|
||||
@ -397,7 +507,6 @@ img {
|
||||
width: 100px;
|
||||
transition: width 0.3s;
|
||||
}
|
||||
/* 进度条颜色区分(可扩展更多规则) */
|
||||
.green {
|
||||
background-color: #28a745;
|
||||
}
|
||||
@ -429,14 +538,59 @@ img {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
.stats-container::-webkit-scrollbar-thumb {
|
||||
background-color: #0ff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.stats-container::-webkit-scrollbar-track {
|
||||
background-color: rgba(0, 255, 255, 0.2);
|
||||
}
|
||||
}
|
||||
.detailBox {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 10vh;
|
||||
width: 300px;
|
||||
padding: 20px 15px;
|
||||
box-sizing: border-box;
|
||||
/* background: rgba(138, 157, 161, 0.5); */
|
||||
background: #040c1c;
|
||||
// border: 2px dashed rgba(29, 214, 255, 0.3);
|
||||
border-right: none;
|
||||
border-radius: 4px;
|
||||
transition: all 0.3s ease;
|
||||
opacity: 0;
|
||||
z-index: -1;
|
||||
|
||||
& > .boxContent {
|
||||
flex: 1;
|
||||
height: 300px;
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: rgba(204, 204, 204, 0.1);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(29, 214, 255, 0.78);
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
&.show {
|
||||
right: 25vw;
|
||||
opacity: 1;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.close {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: 7px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user