代码提交

dev_0.0.1_xq
刘政 2 weeks ago
parent 0fedd81e72
commit 6311b3ff8d

@ -13,18 +13,97 @@
<script setup lang="ts"> <script setup lang="ts">
// keep-alive // keep-alive
import {leftAsideStore} from "@/views/teacher/teacherStatistics/components/mt-edit/store/left-aside";
defineOptions({ defineOptions({
name: 'PreviewIndex' name: 'PreviewIndex'
}); });
import MtPreview from '@/views/teacher/teacherStatistics/components/mt-preview/index.vue'; import MtPreview from '@/views/teacher/teacherStatistics/components/mt-preview/index.vue';
import { onMounted, ref, reactive, onUnmounted } from 'vue'; import {onMounted, ref, reactive, onUnmounted, getCurrentInstance} from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { globalStore } from '@/views/teacher/teacherStatistics/components/mt-edit/store/global'; import { globalStore } from '@/views/teacher/teacherStatistics/components/mt-edit/store/global';
import { useExportJsonToDoneJson } from '@/views/teacher/teacherStatistics/components/mt-edit/composables'; import { useExportJsonToDoneJson } from '@/views/teacher/teacherStatistics/components/mt-edit/composables';
import { objectDeepClone, randomString } from '@/views/teacher/teacherStatistics/components/mt-edit/utils'; import { objectDeepClone, randomString } from '@/views/teacher/teacherStatistics/components/mt-edit/utils';
import { modelApi } from '@/views/teacher/teacherStatistics/utils/request'; import { modelApi } from '@/views/teacher/teacherStatistics/utils/request';
import vueSignalGaudy from "@/views/teacher/teacherStatistics/components/vue-xq-test/vue-signal-gaudy.vue";
import VueImg from "../teacherStatistics/components/vue-xq-test/vue-img.vue";
import VueCamera from "@/views/teacher/teacherStatistics/components/vue-xq-test/vue-camera.vue";
const instance = getCurrentInstance();
instance?.appContext.app.component('vue-my-signal-gaudy', vueSignalGaudy);
instance?.appContext.app.component('vue-my-img', VueImg);
instance?.appContext.app.component('vue-my-camera', VueCamera);
leftAsideStore.registerConfig('工作组件', [
{
id: 'vue-my-signal-gaudy',
title: 'vue遥信02',
type: 'vue',
thumbnail: `${import.meta.env.BASE_URL}svgs/signal-gaudy.svg`,
// thumbnail:"/svgs/signal-gaudy.svg",
props: {
moduleType: {
type: 'inputTypeTag',
val: '遥信',
title: '四遥类型'
},
moduleId: {
type: 'inputSelectId',
val: '',
title: '绑定ID'
},
location: {
type: 'select',
val: 'bottom',
title: '名称位置',
options: [
{
value: 'top',
label: '上'
},
{
value: 'bottom',
label: '下'
},
{
value: 'left',
label: '左'
},
{
value: 'right',
label: '右'
}
]
}
}
},
{
id: 'vue-my-img',
title: '图形组件',
type: 'vue',
thumbnail: '/svgs/image.svg',
props: {
moduleId: {
type: 'upload',
val: '--',
title: '绑定'
}
}
},
{
id: 'vue-my-camera',
title: '监控组件',
type: 'vue',
thumbnail: '/svgs/image.svg',
props: {
moduleId: {
type: 'treeSelectModel',
val: '',
name: '',
title: '绑定摄像头',
}
}
}
]);
let drawerVisible = ref(false); let drawerVisible = ref(false);
let fileNames: Array<{ id: string; name: string }> = reactive([]); let fileNames: Array<{ id: string; name: string }> = reactive([]);

@ -197,7 +197,7 @@ defineExpose({
.scrollbar { .scrollbar {
width: 100%; width: 100%;
height: 94.7vh; height: 100%;
} }
.canvasArea { .canvasArea {

@ -1,170 +0,0 @@
<template>
<el-row :gutter="20" style="display: flex; align-items: center">
<el-col :span="24" class="centered-col">
<el-text class="mx-1" size="large" style="font-size: 16px; margin-bottom: 15px"
>配置说明</el-text
>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24" class="centered-col">
<el-table
:data="tableData"
:header-cell-style="{ color: '#3b3b3b ' }"
:style="{ height: '200px' }"
>
<!-- 序号 -->
<el-table-column
type="index"
label="序号"
:resizable="false"
min-width="60"
align="center"
/>
<!-- 站端名称 -->
<el-table-column
prop="pilotLamp"
label="指示灯"
:resizable="false"
width="120"
align="center"
/>
<el-table-column label="正常时状态" :resizable="false" align="center" min-width="180">
<template #default="scope">
<el-tag v-if="!scope.row.order" type="info" :style="{ fontSize: computedSize }"
>不亮</el-tag
>
<el-tag v-else type="primary" :style="{ fontSize: computedSize }"></el-tag>
</template>
</el-table-column>
<!-- 事件内容 -->
<el-table-column
prop="explain"
label="说明"
:resizable="false"
min-width="280"
show-overflow-tooltip
align="left"
/>
</el-table>
</el-col>
</el-row>
</template>
<script lang="ts" setup>
import { ref, reactive, watch, onMounted, computed } from 'vue';
const props = defineProps({
fontFamily: {
type: String,
default: '黑体'
},
fontSize: {
type: Number,
default: 12
},
testColor: {
type: String,
default: '#ffffff'
}
});
const form = reactive({
fileId: null,
fileName: null,
fileDate: null
});
//
interface UnitException {
pilotLamp: string; //
order: boolean; //
explain: string; //
}
const tableData: UnitException[] = [
{
pilotLamp: '火灾',
order: false,
explain: '未隔离系统中一个或多个设备启动了控制器的报警,变亮'
},
{
pilotLamp: '故障',
order: false,
explain: '系统发生一个或多个故障,变亮'
},
{
pilotLamp: '隔离',
order: false,
explain: '系统中任何设备或防区被隔离,变亮'
},
{
pilotLamp: '主供电源',
order: true,
explain: '交流电源接通时亮'
},
{
pilotLamp: '备用电源',
order: false,
explain: '交流电源不接通,且备用电源(直流24V)接通时,变亮'
},
{
pilotLamp: '讯响器屏蔽',
order: false,
explain: '外部讯响器发生故障时,变亮'
},
{
pilotLamp: '测试模式',
order: false,
explain: '控制板处于测试方式时,变亮'
},
{
pilotLamp: '电源故障',
order: false,
explain: '主电或备电发生故障,变亮'
},
{
pilotLamp: '讯响器故障',
order: false,
explain: '外部讯响器发生故障,变亮'
},
{
pilotLamp: '接地故障',
order: false,
explain: '控制回路发生直流接地时,此信号灯亮'
},
{
pilotLamp: '系统故障',
order: false,
explain: '控制器中主处理器发生故障,变亮'
}
];
//
let computedSize = computed({
//
get() {
return props.fontSize + 'px';
}, //
set(val) {
console.log('有人修改了fullName', val);
}
});
</script>
<style scoped>
.centered-col .el-table {
font-size: v-bind('computedSize');
/* font-size: 12px; */
}
.centered-col {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
}
</style>

@ -1,234 +0,0 @@
<template>
<div class="cardInfo">
<el-card shadow="card">
<h2 class="cardHead">{{ headline }}</h2>
<!-- 动态生成 el-row el-col -->
<template v-for="(chunk, rowIndex) in chunkArray(floorOne, 6)" :key="rowIndex">
<el-row :gutter="10" class="mb-4">
<el-col v-for="(item, colIndex) in chunk" :key="colIndex" :span="24 / chunk.length">
<div>
<!-- class="grid-content" -->
<el-tag v-if="item.policeType == '1'" type="primary">{{ item.name }}</el-tag>
<el-tag v-else-if="item.policeType == '2'" type="warning">{{ item.name }}</el-tag>
<el-tag v-else type="danger">{{ item.name }}</el-tag>
<!-- {{ item.name }} -->
</div>
</el-col>
</el-row>
</template>
</el-card>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, computed } from 'vue';
const props = defineProps({
fontFamily: {
type: String,
default: 'Segoe UI'
},
fontSize: {
type: Number,
default: 14
},
headline: {
type: String,
default: '自定义标题'
}
});
let computedSize = computed({
//
get() {
return props.fontSize + 'px';
}, //
set(val) {
console.log('有人修改了fullName', val);
}
});
interface CallThePolice {
id: string; //id
name: string; //
policeType: string; //
}
//
function chunkArray<T>(array: T[], size: number): T[][] {
const result: T[][] = [];
for (let i = 0; i < array.length; i += size) {
result.push(array.slice(i, i + size));
}
return result;
}
// policeType
function getBackgroundColor(policeType: string): string {
switch (policeType) {
case '1':
return ''; //
case '2':
return 'rgb(238, 190, 119)'; //
case '3':
return 'rgb(196, 86, 86)'; //
default:
return ''; //
}
}
let val = ref('1');
let floorOne = reactive<Array<CallThePolice>>([
{
id: '1',
name: '1号感烟',
policeType: '1'
},
{
id: '2',
name: '2号感烟',
policeType: '1'
},
{
id: '3',
name: '3号感烟',
policeType: '2'
},
{
id: '4',
name: '4号感烟',
policeType: '1'
},
{
id: '5',
name: '5号感烟',
policeType: '1'
},
{
id: '6',
name: '6号感烟',
policeType: '1'
},
{
id: '7',
name: '7号感烟',
policeType: '1'
},
{
id: '8',
name: '8号感烟',
policeType: '1'
},
{
id: '9',
name: '9号感烟',
policeType: '1'
},
{
id: '10',
name: '10号感烟',
policeType: '1'
},
{
id: '11',
name: '11号感烟',
policeType: '1'
},
{
id: '12',
name: '12号感烟',
policeType: '3'
},
{
id: '13',
name: '13号感烟',
policeType: '2'
},
{
id: '14',
name: '14号感烟',
policeType: '1'
},
{
id: '15',
name: '15号感烟',
policeType: '1'
},
{
id: '16',
name: '16号感烟',
policeType: '3'
},
{
id: '17',
name: '17号感烟',
policeType: '1'
},
{
id: '18',
name: '18号感烟',
policeType: '1'
},
{
id: '19',
name: '1号声光报警器',
policeType: '1'
},
{
id: '20',
name: '2号声光报警器',
policeType: '1'
},
{
id: '21',
name: '1号手报',
policeType: '1'
},
{
id: '22',
name: '2号手报',
policeType: '2'
}
]);
</script>
<style scoped>
/* 去除 el-card__body 的默认边距 */
:deep(.el-card__body) {
padding-top: 5px !important;
padding-bottom: 0 !important;
/* margin: 2 !important; */
}
.cardInfo {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
/* max-width: 480px; */
/* color: v-bind('props.testColor'); */
font-family: v-bind('props.fontFamily');
/* font-family: 'Segoe UI'; */
font-size: v-bind('computedSize');
}
.card {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.cardHead {
margin: 0;
padding-bottom: 5px;
/* padding-bottom: 10px; */
text-align: center;
}
.grid-content {
/* background-color: #9e0000; */
display: flex;
flex-direction: column; /* 垂直排列 */
justify-content: center; /* 垂直居中 */
align-items: flex-start;
}
</style>

@ -1,501 +0,0 @@
<template>
<el-form :model="form" label-width="auto" style="max-width: 100%; margin-left: 2vh" inline>
<!-- 第一行 -->
<el-row :gutter="1">
<!-- 设备名称 -->
<el-col :span="6">
<el-form-item label="设备名称">
<el-input v-model="form.fileName" style="width: 100%" />
</el-form-item>
</el-col>
<!-- 所属展柜 -->
<el-col :span="6">
<el-form-item label="所属展柜">
<el-input v-model="form.fileName" />
</el-form-item>
</el-col>
<!-- 所属展柜 -->
<el-col :span="6">
<el-form-item label="子系统" style="width: 100%">
<el-select v-model="form.fileId" style="width: 100%">
<el-option label="消防系统" value="shanghai" />
<el-option label="识别系统" value="beijing" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- 第二行 -->
<el-row :gutter="1">
<el-col :span="6" style="display: flex; align-items: left">
<el-form-item label="告警级别" style="width: 100%">
<el-select v-model="form.fileDate" style="width: 100%">
<el-option label="危急" value="shanghai" />
<el-option label="一般" value="beijing" />
<el-option label="正常" value="chengdu" />
</el-select>
</el-form-item>
</el-col>
<!-- 创建时间 -->
<el-col :span="8">
<el-form-item label="时间" style="display: flex; align-items: left">
<el-date-picker
v-model="form.fileDate"
type="daterange"
range-separator="-"
start-placeholder="开始时间"
end-placeholder="结束时间"
size="default"
/>
</el-form-item>
</el-col>
<el-col :span="5"> </el-col>
<el-col :span="5">
<el-button type="primary">查询</el-button>
<el-button type="info">重置</el-button>
</el-col>
</el-row>
</el-form>
<el-table
:data="tableData"
style="width: 100%; margin-left: 2vh"
:row-class-name="tableRowClassName"
:header-cell-style="{ color: '#3b3b3b ' }"
:style="{ 'max-height': '470px' }"
>
<!-- 序号 -->
<el-table-column type="index" label="序号" :resizable="false" min-width="60" align="center" />
<!-- 站端名称 -->
<el-table-column
prop="inkanetName"
label="站端名称"
:resizable="false"
width="180"
align="center"
/>
<!-- 时间 -->
<el-table-column prop="date" label="时间" :resizable="false" min-width="180" align="center" />
<!-- 设备名称 -->
<el-table-column
prop="equipmentName"
label="设备名称"
:resizable="false"
min-width="180"
align="center"
/>
<!-- 事件内容 -->
<el-table-column
prop="eventContent"
label="事件内容"
:resizable="false"
min-width="280"
show-overflow-tooltip
align="center"
/>
<!-- 当前测量值 -->
<el-table-column
v-if="unauthorizedBool"
prop="measurementValue"
label="当前测量值"
:resizable="false"
min-width="180"
show-overflow-tooltip
align="center"
/>
<!-- 越限范围 -->
<el-table-column
v-if="unauthorizedBool"
prop="limit"
label="越限范围"
:resizable="false"
min-width="180"
show-overflow-tooltip
align="center"
/>
<!-- 偏移量 -->
<el-table-column
v-if="unauthorizedBool"
prop="offset"
label="偏移量"
:resizable="false"
min-width="180"
show-overflow-tooltip
align="center"
/>
<!-- 告警级别 -->
<el-table-column
v-if="wholeSiteMessageBool"
prop="alarmLevel"
label="告警级别"
:resizable="false"
align="center"
min-width="180"
>
<template #default="scope">
<el-tag v-if="scope.row.alarmLevel === 1" type="danger"></el-tag>
<el-tag v-else-if="scope.row.alarmLevel === 2" type="warning">一般</el-tag>
<el-tag v-else type="primary">正常</el-tag>
</template>
</el-table-column>
<!-- 所属子系统 -->
<el-table-column
prop="subsystem"
label="所属子系统"
:resizable="false"
min-width="180"
align="center"
/>
<!-- 处理结果 -->
<el-table-column
v-if="wholeSiteMessageBool || unauthorizedBool"
prop="processingStructure"
label="处理结果"
:resizable="false"
min-width="180"
align="center"
/>
<!-- 操作 -->
<el-table-column label="操作" :resizable="false" align="center" min-width="180" fixed="right">
<template #default="scope">
<el-button v-if="scope.row.operation === 0" type="primary" size="small"></el-button>
<el-tag v-else type="primary">已解决</el-tag>
</template>
</el-table-column>
</el-table>
<div style="margin-left: 2vh">
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[10, 15, 20]"
:pager-count="3"
size="default"
layout=",total,sizes,-> ,prev, pager, next"
:total="pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, watch, onMounted } from 'vue';
onMounted(() => {
loadRequestUrl(props.dataSource);
});
const props = defineProps({
dataSource: {
type: String,
default: '--'
}
});
let requestUrl = ref<string>();
let wholeSiteMessageBool = ref(false); //
let unitExceptionBool = ref(false); //
let unauthorizedBool = ref(false); //
const loadRequestUrl = (moduleId: string) => {
console.log('moduleId:', moduleId);
switch (moduleId) {
case 'wholeSiteMessage':
tableData.value = [];
wholeSiteMessageBool.value = true;
unitExceptionBool.value = false;
unauthorizedBool.value = false;
requestUrl.value = '/api/wholeSiteMessage';
//
tableData.value = wholeSiteMessageList;
break;
case 'unitException':
tableData.value = [];
wholeSiteMessageBool.value = false;
unitExceptionBool.value = true;
unauthorizedBool.value = false;
requestUrl.value = '/api/unitException';
//
tableData.value = unitExceptionList;
break;
case 'unauthorized':
tableData.value = [];
wholeSiteMessageBool.value = false;
unitExceptionBool.value = false;
unauthorizedBool.value = true;
requestUrl.value = '/api/unauthorized';
//
tableData.value = unauthorizedBoolList;
break;
}
};
watch(
() => props.dataSource,
(newVal, oldVal) => {
console.log('moduleId:', newVal, oldVal);
loadRequestUrl(newVal);
}
);
let currentPage = ref(1);
let pageSize = ref(10);
let pageTotal = ref(45);
const handleSizeChange = (val: number) => {
console.log('size点击:', `${val} items per page`);
};
const handleCurrentChange = (val: number) => {
console.log('Current点击:', `current page: ${val}`);
};
const form = reactive({
fileId: null,
fileName: null,
fileDate: null
});
//
interface WholeSiteMessage {
inkanetName: string; //
date: string; //
equipmentName: string; //
eventContent: string; //
alarmLevel: number; // 1 2 3
subsystem: string; //
processingStructure: string; //
operation: number; // 0 1
}
//
interface UnauthorizedBool {
inkanetName: string; //
date: string; //
equipmentName: string; //
eventContent: string; //
offset: number; //
limit: string; //
measurementValue: string; //
subsystem: string; //
processingStructure: string; //
operation: number; // 0 1
}
//
interface UnitException {
inkanetName: string; //
date: string; //
equipmentName: string; //
eventContent: string; //
subsystem: string; //
operation: number; // 0 1
}
const tableRowClassName = ({ row }: { row: WholeSiteMessage }) => {
if (row.alarmLevel === 1) {
return 'danger-row';
} else if (row.alarmLevel === 2) {
return 'warning-row';
}
return '';
};
let tableData = ref<any[]>([]);
const unitExceptionList: UnitException[] = [
{
inkanetName: '南河变电站',
date: '2026-02-04 20:48:08',
equipmentName: '3号感烟探头',
eventContent: '生产综合楼1楼蓄电池室3号感烟探头报警,生',
subsystem: '消防系统',
operation: 0
},
{
inkanetName: '南河变电站',
date: '2026-02-04 20:48:08',
equipmentName: '3号感烟探头',
eventContent: '生产综合楼1楼蓄电池室3号感烟探头报',
subsystem: '消防系统',
operation: 0
},
{
inkanetName: '南河变电站',
date: '2026-02-04 20:48:08',
equipmentName: '3号感烟探头',
eventContent: '生产综合楼1楼蓄电池室3号感烟探头报警',
subsystem: '消防系统',
operation: 0
}
];
const unauthorizedBoolList: UnauthorizedBool[] = [
{
inkanetName: '南河变电站',
date: '2026-02-04 20:48:08',
equipmentName: '3号感烟探头',
eventContent: '生产综合楼1楼蓄电池室3号感烟探头报警,生产综合楼1楼蓄电池室3号感烟探头报警',
offset: 10,
limit: '10-20',
measurementValue: '10.0',
subsystem: '消防系统',
processingStructure: '成功',
operation: 0
},
{
inkanetName: '南河变电站',
date: '2026-02-04 20:48:08',
equipmentName: '3号感烟探头',
eventContent: '生产综合楼1楼蓄电池室3号感烟探头报警,生产综合楼1楼蓄电池室3号感烟探头报警',
offset: 10,
limit: '10-20',
measurementValue: '10.0',
subsystem: '消防系统',
processingStructure: '成功',
operation: 0
},
{
inkanetName: '南河变电站',
date: '2026-02-04 20:48:08',
equipmentName: '3号感烟探头',
eventContent: '生产综合楼1楼蓄电池室3号感烟探头报警,生产综合楼1楼蓄电池室3号感烟探头报警',
offset: 10,
limit: '10-20',
measurementValue: '10.0',
subsystem: '消防系统',
processingStructure: '成功',
operation: 0
}
];
const wholeSiteMessageList: WholeSiteMessage[] = [
{
inkanetName: '南河变电站',
date: '2026-02-04 20:48:08',
equipmentName: '3号感烟探头',
eventContent: '生产综合楼1楼蓄电池室3号感烟探头报警,生产综合楼1楼蓄电池室3号感烟探头报警',
alarmLevel: 1,
subsystem: '消防系统',
processingStructure: '成功',
operation: 0
},
{
inkanetName: '南河变电站',
date: '2026-01-27 15:28:08',
equipmentName: '荣耀科技',
eventContent: '荣耀科技打卡指纹识别告警',
alarmLevel: 3,
subsystem: '指纹识别',
processingStructure: '成功',
operation: 0
},
{
inkanetName: '南河变电站',
date: '2026-01-25 12:48:08',
equipmentName: '电子围栏',
eventContent: '电子围栏一区(东一)入侵告警',
alarmLevel: 2,
subsystem: '安全防范',
processingStructure: '成功',
operation: 1
},
{
inkanetName: '南河变电站',
date: '2026-01-26 15:28:08',
equipmentName: '荣耀科技',
eventContent: '荣耀科技研发部人脸识别告警',
alarmLevel: 3,
subsystem: '人脸识别',
processingStructure: '成功',
operation: 0
},
{
inkanetName: '南河变电站',
date: '2026-02-04 20:48:08',
equipmentName: '3号感烟探头',
eventContent: '生产综合楼1楼蓄电池室3号感烟探头报警',
alarmLevel: 3,
subsystem: '消防系统',
processingStructure: '成功',
operation: 0
},
{
inkanetName: '南河变电站',
date: '2026-01-27 15:28:08',
equipmentName: '荣耀科技',
eventContent: '荣耀科技打卡指纹识别告警',
alarmLevel: 3,
subsystem: '指纹识别',
processingStructure: '成功',
operation: 0
},
{
inkanetName: '南河变电站',
date: '2026-01-25 12:48:08',
equipmentName: '电子围栏',
eventContent: '电子围栏一区(东一)入侵告警',
alarmLevel: 3,
subsystem: '安全防范',
processingStructure: '成功',
operation: 1
},
{
inkanetName: '南河变电站',
date: '2026-01-26 15:28:08',
equipmentName: '荣耀科技',
eventContent: '荣耀科技研发部人脸识别告警',
alarmLevel: 3,
subsystem: '人脸识别',
processingStructure: '成功',
operation: 0
},
{
inkanetName: '南河变电站',
date: '2026-02-04 20:48:08',
equipmentName: '3号感烟探头',
eventContent: '生产综合楼1楼蓄电池室3号感烟探头报警',
alarmLevel: 3,
subsystem: '消防系统',
processingStructure: '成功',
operation: 0
},
{
inkanetName: '南河变电站',
date: '2026-01-27 15:28:08',
equipmentName: '荣耀科技',
eventContent: '荣耀科技打卡指纹识别告警',
alarmLevel: 3,
subsystem: '指纹识别',
processingStructure: '成功',
operation: 0
}
];
</script>
<style>
.el-table .danger-row {
/* background-color: #3b3b3b !important; */
color: rgb(196, 86, 86) !important;
}
.el-table .warning-row {
/* background-color: #fdf6ec !important; */
color: rgb(184, 130, 48) !important;
}
</style>

@ -1,77 +0,0 @@
<template>
<div>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="Date" width="180" />
<el-table-column prop="name" label="Name" width="180" />
<el-table-column prop="address" label="Address" />
</el-table>
</div>
</template>
<script lang="ts" setup>
const tableData = [
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}
];
</script>
<style scoped>
/* 修改表格整体背景色 */
::v-deep .el-table {
background-color: #40beff; /* 浅蓝色背景 */
}
/* 修改表头背景色和文字颜色 */
::v-deep .el-table th.el-table__cell {
background-color: #2e349e; /* 深蓝色表头 */
color: white; /* 白色文字 */
font-weight: bold;
}
/* 修改表头边框颜色 */
::v-deep .el-table th.el-table__cell {
border: 1px solid #151a3d; /* 深色边框 */
}
/* 修改奇偶行背景色 */
::v-deep .el-table .el-table__body-wrapper tr.el-table__row:nth-child(odd) {
background-color: #40beff; /* 奇数行使用浅蓝色 */
}
::v-deep .el-table .el-table__body-wrapper tr.el-table__row:nth-child(even) {
background-color: #2e349e; /* 偶数行使用深蓝色 */
}
/* 修改鼠标悬停时的行颜色 */
::v-deep .el-table .el-table__body tr:hover > td {
background-color: rgba(64, 190, 255, 0.7); /* 半透明浅蓝色悬停效果 */
}
/* 修改选中行的颜色 */
::v-deep .el-table .el-table__body tr.current-row > td {
background-color: #151a3d; /* 选中行使用最深蓝色 */
}
/* 修改单元格边框颜色 */
::v-deep .el-table td.el-table__cell {
border: 1px solid #151a3d; /* 深色边框 */
}
</style>

@ -1,311 +0,0 @@
<template>
<el-card class="card">
<h2 class="cardHead">基本信息</h2>
<div class="cardBody">
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 名称 </el-col>
<el-col :span="4">
<el-tag type="primary">火灾报警系统主机</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 产品型号 </el-col>
<el-col :span="4">
<el-tag type="primary">JB-QB-GST200</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 厂家 </el-col>
<el-col :span="4">
<el-tag type="primary">海湾公司</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 投运日期 </el-col>
<el-col :span="4">
<el-tag type="primary">2015-10-10</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 电源电压 </el-col>
<el-col :span="4">
<el-tag type="primary">220V AC</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 频率 </el-col>
<el-col :span="4">
<el-tag type="primary">50Hz</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 输出电压 </el-col>
<el-col :span="4">
<el-tag type="primary">24V DC</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 输出电流 </el-col>
<el-col :span="4">
<el-tag type="primary">5A</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 环境温度 </el-col>
<el-col :span="4">
<el-tag type="primary">-5 ~ 45</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 相对湿度 </el-col>
<el-col :span="4">
<el-tag type="primary">5% ~ 95%</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 维保单位 </el-col>
<el-col :span="4">
<el-tag type="primary">陕西消防科技有限公司</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 联系电话 </el-col>
<el-col :span="4">
<el-tag type="primary">188*****00 </el-tag>
</el-col>
</el-row>
</div>
</el-card>
<!-- :append-to-body="true" -->
<el-dialog
v-model="dialogTableVisible"
title="灭火动作流程"
style="height: 60vh"
width="45%"
:append-to-body="true"
>
<el-scrollbar height="42vh">
<el-timeline mode="alternate-reverse">
<el-timeline-item
v-for="(activity, index) in activities"
:key="index"
center
:timestamp="activity.timestamp"
>
{{ activity.content }}
</el-timeline-item>
</el-timeline>
</el-scrollbar>
<!-- 按钮 -->
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogTableVisible = false">退出</el-button>
</div>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { computed, ref, watch, onMounted } from 'vue';
let dialogTableVisible = ref(false);
const props = defineProps({
fontFamily: {
type: String,
default: 'Segoe UI'
},
fontSize: {
type: Number,
default: 14
},
testColor: {
type: String,
default: '#000000'
},
testBool: {
type: Boolean,
default: true
},
dataSource: {
type: String,
default: '--'
}
});
const activities = [
{
content: '灭火允许',
timestamp: '2018-04-15'
},
{
content: '手动启动',
timestamp: '2018-04-16'
},
{
content: '紧急停止',
timestamp: '2018-04-17'
},
{
content: '手动启动',
timestamp: '2018-04-18'
},
{
content: '灭火允许',
timestamp: '2018-04-15'
},
{
content: '手动启动',
timestamp: '2018-04-16'
},
{
content: '紧急停止',
timestamp: '2018-04-17'
},
{
content: '手动启动',
timestamp: '2018-04-18'
}
];
onMounted(() => {
loadDataSource(props.dataSource);
});
watch(
() => props.dataSource,
(newVal, oldVal) => {
loadDataSource(newVal);
}
);
//
let globalOverviewBool = ref(false);
//
let fireExtinguishingBool = ref(false);
//
let firePoliceBool = ref(false);
function loadDataSource(val: string) {
if (val === 'globalOverview') {
globalOverviewBool.value = true;
fireExtinguishingBool.value = false;
firePoliceBool.value = false;
} else if (val === 'fireExtinguishing') {
globalOverviewBool.value = false;
fireExtinguishingBool.value = true;
firePoliceBool.value = false;
} else if (val === 'firePolice') {
globalOverviewBool.value = false;
fireExtinguishingBool.value = false;
firePoliceBool.value = true;
}
}
let computedSize = computed({
//
get() {
return props.fontSize + 'px';
}, //
set(val) {
console.log('有人修改了fullName', val);
}
});
</script>
<style scoped>
.blue-circle {
width: 12px;
height: 12px;
border-radius: 50%;
background-color: #409eff;
display: inline-block;
margin-left: 5px;
vertical-align: middle;
}
.blueBordered {
background-color: rgb(217, 236, 255);
border: 2px solid rgb(160, 207, 255);
}
.redBordered {
background-color: rgb(253, 226, 226);
border: 2px solid rgb(250, 182, 182);
}
.greenBordered {
background-color: rgb(225, 243, 216);
border: 2px solid rgb(179, 225, 157);
}
:deep(.el-card__body) {
padding: 0;
padding-top: 10px;
padding-left: 10px;
}
:deep(.adTextDetailDialogClass .el-dialog__body) {
max-height: calc(100vh - 150px);
overflow: auto;
border-top: 1px solid #dfdfdf;
border-bottom: 1px solid #dfdfdf;
}
:deep(.adTextDetailDialogClass .el-dialog) {
position: fixed;
height: 20vh !important;
background: #000;
left: 0 !important;
right: 0 !important;
top: 0 !important;
bottom: 0 !important;
margin: auto !important;
}
.el-row .el-col {
margin-bottom: 6px; /* 设置上下间距 */
}
P:hover {
background-color: #f0f0f0; /* 悬停时的底色,您可以根据需要调整颜色 */
}
.card {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
/* max-width: 480px; */
color: v-bind('props.testColor');
font-family: v-bind('props.fontFamily');
/* font-family: 'Segoe UI'; */
font-size: v-bind('computedSize');
}
.cardHead {
margin: 0;
padding: 0px;
padding-bottom: 5px;
text-align: center;
}
.cardBody {
width: 100%;
margin: 0 0%;
padding: 0px 0%;
/* padding-bottom: 15px; */
}
</style>

@ -1,93 +0,0 @@
<template>
<div class="cardInfo">
<el-card shadow="card" style="height: 100%">
<h2 class="cardHead">主机</h2>
<el-row :gutter="20">
<el-col :span="6">
<el-tag type="success">运行</el-tag>
</el-col>
<el-col :span="6">
<el-tag type="info">报警</el-tag>
</el-col>
<el-col :span="6">
<el-button key="primary" type="primary" size="small" text bg> 自动启动 </el-button>
</el-col>
<el-col :span="6">
<el-button key="info" type="info" size="small" text bg>手动启动</el-button>
</el-col>
</el-row>
</el-card>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, computed } from 'vue';
const props = defineProps({
fontFamily: {
type: String,
default: 'Segoe UI'
},
fontSize: {
type: Number,
default: 14
},
headline: {
type: String,
default: '自定义标题'
}
});
let computedSize = computed({
//
get() {
return props.fontSize + 'px';
}, //
set(val) {
console.log('有人修改了fullName', val);
}
});
</script>
<style scoped>
/* 去除 el-card__body 的默认边距 */
:deep(.el-card__body) {
padding-top: 5px !important;
padding-bottom: 0 !important;
/* margin: 2 !important; */
}
.cardInfo {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
/* max-width: 480px; */
/* color: v-bind('props.testColor'); */
font-family: v-bind('props.fontFamily');
/* font-family: 'Segoe UI'; */
font-size: v-bind('computedSize');
}
.card {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.cardHead {
margin: 0;
padding-top: 10px;
padding-bottom: 15px;
/* padding-bottom: 10px; */
text-align: center;
}
.grid-content {
/* background-color: #9e0000; */
display: flex;
flex-direction: column; /* 垂直排列 */
justify-content: center; /* 垂直居中 */
align-items: flex-start;
}
</style>

@ -1,117 +0,0 @@
<template>
<div class="slider-demo-block">
<span class="demonstration">温度</span>
<el-slider v-model="temperatureVal" :format-tooltip="temperatureValConst" disabled />
</div>
<div class="slider-demo-block">
<span class="demonstration">湿度</span>
<el-slider v-model="humidityVal" :format-tooltip="humidityValConst" disabled />
</div>
<div class="slider-demo-block">
<span class="demonstration">风力</span>
<el-slider v-model="windVal" :format-tooltip="windValConst" disabled />
</div>
<div class="slider-demo-block">
<span class="demonstration">雨量</span>
<el-slider v-model="rainVal" :format-tooltip="rainValConst" disabled />
</div>
</template>
<script setup lang="ts">
import { ref, toRefs } from 'vue';
// let props = defineProps({
// temperatureVal: Number,
// humidityVal: Number,
// windVal: Number,
// rainVal: Number,
// draggable: Boolea
// })
const props = defineProps({
temperatureVal: {
type: Number,
default: 12
},
humidityVal: {
type: Number,
default: 12
},
windVal: {
type: Number,
default: 12
},
rainVal: {
type: Number,
default: 12
}
});
let { temperatureVal, humidityVal, windVal, rainVal } = toRefs(props);
// let value2 = ref<number>(props.humidityVal ?? 0);
// let value3 = ref<number>(props.windVal ?? 0);
// let value4 = ref<number>(props.rainVal ?? 0);
const formatTooltip = (val: number) => {
return val / 100;
};
//
const temperatureValConst = (val: number) => {
return val + ' ℃';
};
// 湿
const humidityValConst = (val: number) => {
return val + ' %RH';
};
// wind
const windValConst = (val: number) => {
return val / 10 + ' m/s';
};
// rainVal
const rainValConst = (val: number) => {
return val + ' mm';
};
</script>
<style scoped>
.slider-demo-block {
max-width: 300px;
display: flex;
align-items: center;
}
.slider-demo-block .el-slider {
margin-top: 0;
margin-left: 12px;
}
.slider-demo-block .demonstration {
font-size: 14px;
color: var(--el-text-color-secondary);
line-height: 35px;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-bottom: 0;
}
.slider-demo-block .demonstration + .el-slider {
flex: 0 0 70%;
}
/* 添加以下样式来缩小滑块圆圈 */
:deep(.el-slider__button) {
width: 14px !important; /* 默认是 20px */
height: 14px !important; /* 默认是 20px */
border-radius: 50%; /* 确保是圆形 */
}
/* 如果你也想缩小激活状态下的圆圈 */
:deep(.el-slider__button-wrapper:hover .el-slider__button) {
width: 20px !important; /* 悬停时稍微大一点 */
height: 20px !important;
}
</style>

@ -1,98 +0,0 @@
<template>
<el-card class="card">
<template #header>
<h2 class="cardHead">{{ props.headline }}</h2>
</template>
<div class="cardBody">
<p>2025-04-25 14:22:17 2号主变油色谱总烃超标</p>
<p>2018-03-21 15:28:11 220kV GIS室O2气体含量低报警2号传感器O2浓度15%</p>
<p>2018-04-25 14:22:17 2号主变油色谱总烃超标</p>
<p>2018-03-21 15:28:11 220kV GIS室O2气体含量低报警2号传感器O2浓度15%</p>
<p>2018-04-25 14:22:17 2号主变油色谱总烃超标</p>
<p>2018-03-21 15:28:11 220kV GIS室O2气体含量低报警2号传感器O2浓度15%</p>
</div>
</el-card>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { globalStore } from '@/components/mt-edit/store/global';
const props = defineProps({
fontFamily: {
type: String,
default: 'Segoe UI'
},
fontSize: {
type: Number,
default: 14
},
testColor: {
type: String,
default: '#000000'
},
headline: {
type: String,
default: '自定义标题'
}
});
console.log();
function test2() {
console.log('props:', props);
}
let computedSize = computed({
//
get() {
return props.fontSize + 'px';
}, //
set(val) {
console.log('有人修改了fullName', val);
}
});
</script>
<style scoped>
:deep(.el-card__body) {
margin: 0;
padding: 0px;
}
:deep(.el-card__header) {
margin: 0;
padding: 10px 0px;
}
P {
margin: 3px 0px;
padding: 2px;
transition: background-color 0.3s ease;
}
P:hover {
background-color: #f0f0f0; /* 悬停时的底色,您可以根据需要调整颜色 */
}
.card {
margin: 0;
padding: 0;
height: 100%;
width: 100;
/* max-width: 480px; */
color: v-bind('props.testColor');
font-family: v-bind('props.fontFamily');
/* font-family: 'Segoe UI'; */
font-size: v-bind('computedSize');
}
.cardHead {
margin: 0;
padding: 0px;
text-align: center;
}
.cardBody {
margin: 0;
padding: 0px;
padding-bottom: 15px;
}
</style>

@ -1,336 +0,0 @@
<template>
<!-- <div style="display: flex; gap: 10px; align-items: center">
<el-popover
:width="300"
:visible="null"
popper-style="box-shadow: rgb(14 18 22 / 35%) 0px 10px 38px -10px, rgb(14 18 22 / 20%) 0px 10px 20px -15px; padding: 20px;"
>
<template #reference>
<el-text
style="font-weight: bold; text-align: center; display: block"
type="primary"
color="rgb(236, 245, 255)"
>
{{ computedVal }}
</el-text>
</template>
<template #default>
<div class="demo-rich-conent" style="display: flex; gap: 2px; flex-direction: column">
<div class="demo-progress">
<el-progress
type="dashboard"
:width="100"
:percentage="percentage"
:color="colors"
:format="customFormat"
/>
</div>
<el-row :gutter="6">
<el-col :span="12" :xs="24" :sm="12" :md="6" class="elColInfo">
<el-statistic title="绑定ID" :value="null">
<template #suffix>
<el-tag size="default" type="primary">{{ moduleId }}</el-tag>
</template>
</el-statistic>
</el-col>
<el-col :span="12" :xs="24" :sm="12" :md="12" class="elColInfo">
<el-statistic title="节点名称" :value="null">
<template #suffix>
<el-tag size="default" type="success">{{ modeName }}</el-tag>
</template>
</el-statistic>
</el-col>
<el-col :span="12" :xs="24" :sm="12" :md="6" class="elColInfo">
<el-statistic title="类型" :value="null">
<template #suffix>
<el-tag size="default" type="primary">{{ moduleType }}</el-tag>
</template>
</el-statistic>
</el-col>
</el-row>
</div>
</template>
</el-popover>
<el-tag type="primary">{{ modeName }}</el-tag>
</div> -->
<el-row v-if="location === 'top'">
<el-col :span="24" class="flex-center">
<el-tag type="primary" size="small" style="opacity: 0.9">
<el-text type="primary" style="max-width: 65px" size="small" truncated>
{{ modeName }}
</el-text>
</el-tag>
</el-col>
</el-row>
<el-row justify="center">
<el-col :span="12" class="flex-center" v-if="location === 'left'">
<el-tag type="primary" size="small" style="opacity: 0.9">
<el-text type="primary" style="max-width: 65px" size="small" truncated>
{{ modeName }}
</el-text>
</el-tag>
</el-col>
<el-col :span="12" class="flex-center">
<div style="display: flex; gap: 10px; align-items: center">
<el-popover
:width="300"
:disabled="true"
popper-style="box-shadow: rgb(14 18 22 / 35%) 0px 10px 38px -10px, rgb(14 18 22 / 20%) 0px 10px 20px -15px; padding: 20px;"
>
<template #reference>
<el-text style="font-weight: bold; text-align: center; display: block">
{{ computedVal }}
</el-text>
</template>
<template #default>
<div class="demo-rich-conent" style="display: flex; gap: 2px; flex-direction: column">
<div class="demo-progress">
<el-progress
type="dashboard"
:width="100"
:percentage="percentage"
:color="colors"
:format="customFormat"
/>
</div>
<el-row :gutter="6">
<el-col :span="12" :xs="24" :sm="12" :md="6" class="elColInfo">
<el-statistic title="绑定ID" :value="null">
<template #suffix>
<el-tag size="default" type="primary">{{ moduleId }}</el-tag>
</template>
</el-statistic>
</el-col>
<el-col :span="12" :xs="24" :sm="12" :md="12" class="elColInfo">
<el-statistic title="节点名称" :value="null">
<template #suffix>
<el-tag size="default" type="success">{{ modeName }}</el-tag>
</template>
</el-statistic>
</el-col>
<el-col :span="12" :xs="24" :sm="12" :md="6" class="elColInfo">
<el-statistic title="类型" :value="null">
<template #suffix>
<el-tag size="default" type="primary">{{ moduleType }}</el-tag>
</template>
</el-statistic>
</el-col>
</el-row>
</div>
</template>
</el-popover>
</div>
</el-col>
<el-col :span="12" class="flex-center" v-if="location === 'right'">
<el-tag type="primary" size="small" style="opacity: 0.9">
<el-text type="primary" style="max-width: 65px" size="small" truncated>
{{ modeName }}
</el-text>
</el-tag>
</el-col>
</el-row>
<el-row v-if="location === 'bottom'">
<el-col :span="24" class="flex-center">
<el-tag type="primary" size="small" style="opacity: 0.9">
<el-text type="primary" style="max-width: 65px; opacity: 1" size="small" truncated>
{{ modeName }}
</el-text>
</el-tag>
</el-col>
</el-row>
</template>
<script lang="ts" setup>
import { onMounted, ref, computed, onUnmounted, watch } from 'vue';
import { useNodeByModelsStore } from '@/components/mt-edit/store/nodeByModels';
import emitter from '@/utils/emitter';
const nodeByModelsStore = useNodeByModelsStore();
onMounted(() => {
loadingModuleById();
saveodeByModels();
});
onUnmounted(() => {
console.log('组件卸载');
deleteByModels();
emitter.off(props.definitionItemJson.id);
});
const props = defineProps({
moduleType: {
type: String,
default: '--'
},
moduleId: {
type: String,
default: '--'
},
definitionItemJson: {
type: Object,
default: () => ({})
},
location: {
type: String,
default: 'bottom'
}
});
console.log('itemjson:', props.definitionItemJson.id);
function saveodeByModels() {
if (props.moduleId == '' || props.moduleId == undefined || props.moduleId == '--') return;
nodeByModelsStore.saveOrUpdate(props.moduleId, props.definitionItemJson.id);
}
function deleteByModels() {
if (props.moduleId == '' || props.moduleId == undefined || props.moduleId == '--') return;
nodeByModelsStore.delete(props.moduleId, props.definitionItemJson.id);
}
watch(
() => props.moduleId,
(newVal, oldVal) => {
loadingModuleById();
nodeByModelsStore.change(newVal, oldVal, props.definitionItemJson.id);
}
);
emitter.on(props.definitionItemJson.id, (value) => {
console.log('触发事件', value);
loadingModuleById();
});
let moduleUnit = ref<string>();
let modeName = ref<string>();
let percentage = ref<number>();
function getModuleById(moduleId: string) {
const globalData = (window as any).globalData;
if (!globalData || moduleId == undefined || moduleId == '' || props.moduleId == '--') {
console.warn('globalData 未初始化');
return null;
}
// 访
if (globalData instanceof Map) {
// Map
return globalData.get(moduleId);
} else {
//
return globalData[moduleId];
}
}
function loadingModuleById() {
// 使访 globalData
let module = getModuleById(props.moduleId);
if (props.moduleId !== '' && props.moduleId !== undefined && props.moduleId !== '--' && module) {
if (module) {
modeName.value = module.node.name;
percentage.value = module.double;
moduleUnit.value = module.node.unit;
}
}
}
//
let computedVal = computed({
//
get() {
if (percentage.value == undefined && moduleUnit.value == undefined) return '--';
return percentage.value + '' + moduleUnit.value;
},
//
set() {}
});
const customFormat = () => {
//
if (percentage.value == undefined && moduleUnit.value == undefined) return '--';
return percentage.value + '' + moduleUnit.value;
};
const colors = [
{ color: '#f56c6c', percentage: 20 },
{ color: '#e6a23c', percentage: 40 },
{ color: '#5cb87a', percentage: 60 },
{ color: '#1989fa', percentage: 80 },
{ color: '#6f7ad3', percentage: 100 }
];
</script>
<style scoped>
/* 设置固定宽度和文本省略 */
.ellipsis-tag {
width: 65px; /* 设置固定宽度 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
align-items: center; /* 水平居中 */
}
.flex-center {
display: flex;
flex-direction: column; /* 垂直排列 */
justify-content: center; /* 垂直居中 */
align-items: center; /* 水平居中 */
}
.el-statistic {
/* 控制文字大小 */
--el-statistic-content-font-size: 16px;
}
.elColInfo {
text-align: center;
}
:deep(.el-progress__text) {
/* 控制文字大小 */
font-size: 16px !important;
}
.demo-progress .el-progress--line {
margin-bottom: 15px;
max-width: 500px;
}
.demo-progress .el-progress--circle {
margin-right: 15px;
}
.fontStyle {
color: rgb(51, 126, 204);
}
h3 {
margin: 0;
padding: 0;
text-align: center;
/* padding-top: 5px;
padding-bottom: 5px; */
}
.demo-radius .radius {
height: 28px;
min-width: 66px;
width: fit-content;
border: 2px solid rgba(51, 125, 204, 0.205);
border-radius: 0;
padding: 0 8px;
box-sizing: border-box;
}
</style>

@ -1,93 +0,0 @@
<template>
<div class="cardInfo">
<el-card shadow="card" style="height: 100%">
<h2 class="cardHead">主机1111</h2>
<el-row :gutter="20">
<el-col :span="6">
<el-tag type="success">运行</el-tag>
</el-col>
<el-col :span="6">
<el-tag type="info">报警</el-tag>
</el-col>
<el-col :span="6">
<el-button key="primary" type="primary" size="small" text bg> 自动启动 </el-button>
</el-col>
<el-col :span="6">
<el-button key="info" type="info" size="small" text bg>手动启动</el-button>
</el-col>
</el-row>
</el-card>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, computed } from 'vue';
const props = defineProps({
fontFamily: {
type: String,
default: 'Segoe UI'
},
fontSize: {
type: Number,
default: 14
},
headline: {
type: String,
default: '自定义标题'
}
});
let computedSize = computed({
//
get() {
return props.fontSize + 'px';
}, //
set(val) {
console.log('有人修改了fullName', val);
}
});
</script>
<style scoped>
/* 去除 el-card__body 的默认边距 */
:deep(.el-card__body) {
padding-top: 5px !important;
padding-bottom: 0 !important;
/* margin: 2 !important; */
}
.cardInfo {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
/* max-width: 480px; */
/* color: v-bind('props.testColor'); */
font-family: v-bind('props.fontFamily');
/* font-family: 'Segoe UI'; */
font-size: v-bind('computedSize');
}
.card {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.cardHead {
margin: 0;
padding-top: 10px;
padding-bottom: 15px;
/* padding-bottom: 10px; */
text-align: center;
}
.grid-content {
/* background-color: #9e0000; */
display: flex;
flex-direction: column; /* 垂直排列 */
justify-content: center; /* 垂直居中 */
align-items: flex-start;
}
</style>

@ -1,150 +0,0 @@
<template>
<el-card class="card">
<h3 class="cardHead">光字牌</h3>
<div class="cardBody">
<el-row :gutter="0" style="display: flex; align-items: center" class="row-spacing">
<el-col :span="24" class="full-width-col">
<el-tag type="primary" size="large" class="full-width-tag">生产综合楼1楼火灾报警</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center" class="row-spacing">
<el-col :span="24" class="full-width-col">
<el-tag type="danger" size="large" class="full-width-tag blinking-tag"
>生产综合楼2楼火灾报警</el-tag
>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center" class="row-spacing">
<el-col :span="24" class="full-width-col">
<el-tag type="primary" size="large" class="full-width-tag"
>220kV配电装置楼1楼火灾报警</el-tag
>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center" class="row-spacing">
<el-col :span="24" class="full-width-col">
<el-tag type="primary" size="large" class="full-width-tag"
>220kV配电装置楼2楼火灾报警</el-tag
>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center" class="row-spacing">
<el-col :span="24" class="full-width-col">
<el-tag type="primary" size="large" class="full-width-tag">主供电源故障</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center" class="row-spacing">
<el-col :span="24" class="full-width-col">
<el-tag type="primary" size="large" class="full-width-tag">备用电源故障</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="24" class="full-width-col">
<el-tag type="primary" size="large" class="full-width-tag">接地故障</el-tag>
</el-col>
</el-row>
</div>
</el-card>
</template>
<script lang="ts" setup>
import { computed, ref, watch, onMounted } from 'vue';
const props = defineProps({
fontFamily: {
type: String,
default: 'Segoe UI'
},
fontSize: {
type: Number,
default: 14
},
testColor: {
type: String,
default: '#000000'
},
testBool: {
type: Boolean,
default: true
}
});
let computedSize = computed({
//
get() {
return props.fontSize + 'px';
}, //
set(val) {
console.log('有人修改了fullName', val);
}
});
</script>
<style scoped>
.row-spacing {
margin-bottom: 10px; /* 每行之间的间隔 */
}
.full-width-col {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
}
.full-width-tag {
width: 100%; /* 填满父容器 */
text-align: center; /* 文字水平居中 */
display: flex; /* 使用 flexbox */
justify-content: center; /* 文字水平居中 */
align-items: center; /* 文字垂直居中 */
font-size: v-bind('computedSize');
}
/* 闪烁动画 */
.blinking-tag {
animation: blink 1s infinite; /* 1秒一次无限循环 */
}
@keyframes blink {
0%,
100% {
opacity: 1; /* 完全不透明 */
}
50% {
opacity: 0.3; /* 半透明 */
}
}
.card {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
/* max-width: 480px; */
color: v-bind('props.testColor');
font-family: v-bind('props.fontFamily');
/* font-family: 'Segoe UI'; */
font-size: v-bind('computedSize' - 1);
}
.cardHead {
margin: 0;
padding: 0px;
padding-bottom: 5px;
text-align: center;
font-size: v-bind('computedSize' + 2);
}
.cardBody {
width: 100%;
margin: 0 0%;
padding: 0px 0%;
/* padding-bottom: 15px; */
}
</style>

@ -1,112 +0,0 @@
<template>
<!-- <el-input-number v-model="num" :step="2" class="custom-input-number" /> -->
<div style="display: flex; align-items: center">
<el-popover
:width="300"
popper-style="box-shadow: rgb(14 18 22 / 35%) 0px 10px 38px -10px, rgb(14 18 22 / 20%) 0px 10px 20px -15px; padding: 20px;"
>
<template #reference>
<el-icon class="iconStyle" :size="30">
<SwitchFilled />
</el-icon>
</template>
<template #default>
<div class="demo-rich-conent" style="display: flex; gap: 2px; flex-direction: column">
<div class="progress-container">
<div class="input-button-row">
<el-input-number v-model="num" :step="2" class="custom-input-number" />
<el-button-group size="small" direction="horizontal">
<el-button type="primary" :icon="Check" />
<el-button
type="primary"
color="rgb(177, 179, 184)"
@click="num = 0"
:icon="RefreshLeft"
/>
</el-button-group>
</div>
</div>
<el-row :gutter="6">
<el-col :span="12" :xs="24" :sm="12" :md="8" class="elColInfo">
<el-statistic title="绑定ID" value="1100101" />
</el-col>
<el-col :span="12" :xs="24" :sm="12" :md="8" class="elColInfo">
<el-statistic title="状态" :value="null">
<template #suffix>
<el-tag size="default" type="success">开启</el-tag>
</template>
</el-statistic>
</el-col>
<el-col :span="12" :xs="24" :sm="12" :md="8" class="elColInfo">
<el-statistic title="类型" :value="null">
<template #suffix>
<el-tag size="default" type="primary">遥调</el-tag>
</template>
</el-statistic>
</el-col>
</el-row>
</div>
</template>
</el-popover>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import {
ChatLineRound,
Male,
WarningFilled,
SwitchFilled,
Check,
RefreshLeft
} from '@element-plus/icons-vue';
const num = ref(5);
</script>
<style scoped>
.iconStyle {
size: 30;
color: #409eff;
}
.el-statistic {
/* 控制文字大小 */
--el-statistic-content-font-size: 16px;
}
.elColInfo {
text-align: center;
}
.progress-container {
width: 120px;
margin-top: 5px;
margin-bottom: 25px;
}
/* 或者通过CSS变量设置 */
/* :deep(.el-input-number) {
width: 20px;
} */
/* 如果要设置内部输入框的宽度 */
/* :deep(.el-input__wrapper) {
width: 20px;
} */
.input-button-row {
width: 300px;
display: flex;
gap: 35px; /* 设置组件之间的间距 */
align-items: center; /* 垂直居中对齐 */
}
.custom-input-number {
width: 140px; /* 设置自定义宽度 */
}
</style>

@ -1,375 +0,0 @@
<template>
<el-card class="card">
<h2 class="cardHead">运行信息</h2>
<div class="cardBody" v-if="globalOverviewBool">
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 设备状态 </el-col>
<el-col :span="4">
<el-tag type="primary">正常/中断</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 温度 </el-col>
<el-col :span="4">
<el-tag type="primary">23</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 湿度 </el-col>
<el-col :span="4">
<el-tag type="primary">45%RH</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 风力 </el-col>
<el-col :span="4">
<el-tag type="primary">三级5m/s</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 风向 </el-col>
<el-col :span="4">
<el-tag type="primary">东风</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 雨量 </el-col>
<el-col :span="4">
<el-tag type="primary">20mm</el-tag>
</el-col>
</el-row>
</div>
<div class="cardBody" v-if="fireExtinguishingBool">
<el-row style="display: flex; align-items: center">
<el-col :span="24">火灾报警系统</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="1"
>设备状态
<el-tag type="primary">正常/故障</el-tag>
</el-col>
<el-col :span="8" :offset="2"
>通信状态
<el-tag type="primary">正常/中断</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="22" :offset="1"
>火灾总告警
<!-- 带边框的蓝色圆 -->
<div class="blue-circle redBordered"></div>
</el-col>
</el-row>
<el-divider style="margin-top: 10px; margin-bottom: 10px" />
<el-row style="display: flex; align-items: center">
<el-col :span="24">2号主变灭火系统排油注氮灭火</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="7" :offset="1">
启动方式
<el-tag type="primary">自动/手动</el-tag>
</el-col>
<el-col :span="7" :offset="1"
>设备状态
<el-tag type="primary">正常/故障</el-tag>
</el-col>
<el-col :span="7" :offset="1"
>通信状态
<el-tag type="primary">正常/中断</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="7" :offset="1"
>火灾总告警
<div class="blue-circle redBordered"></div>
</el-col>
<el-col :span="7" :offset="1">
<el-popover placement="top" :width="170" trigger="hover" content="查看灭火允许满足条件">
<template #reference>
<el-text class="mx-1" type="primary">灭火允许</el-text>
</template>
</el-popover>
<!-- 带边框的蓝色圆 -->
<div class="blue-circle greenBordered"></div>
</el-col>
<el-col :span="7" :offset="1" style="display: flex; align-items: center">
<el-text class="mx-1" type="primary" @click="dialogTableVisible = true">灭火动作</el-text>
<!-- 带边框的蓝色圆 -->
<div class="blue-circle redBordered"></div>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center; margin-top: 8px">
<el-col :span="5" :offset="1">灭火手动操作</el-col>
<el-col :span="12">
<el-button type="primary" size="small">手动启动</el-button>
<el-button type="primary" size="small">紧急停止</el-button>
</el-col>
</el-row>
</div>
<div class="cardBody" v-if="firePoliceBool">
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 设备状态 </el-col>
<el-col :span="4">
<el-tag type="primary">正常/故障</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 通信状态 </el-col>
<el-col :span="4">
<el-tag type="primary">正常/中断</el-tag>
</el-col>
</el-row>
<el-row :gutter="0" style="display: flex; align-items: center">
<el-col :span="8" :offset="4"> 电源状态</el-col>
<el-col :span="4">
<!-- 主供电源工作/备供电源工作/电源中断 -->
<el-tag type="primary">主供电源工作</el-tag>
</el-col>
</el-row>
</div>
</el-card>
<!-- :append-to-body="true" -->
<el-dialog
v-model="dialogTableVisible"
title="灭火动作流程"
style="height: 60vh"
width="45%"
:append-to-body="true"
>
<el-scrollbar height="42vh">
<el-timeline mode="alternate-reverse">
<el-timeline-item
v-for="(activity, index) in activities"
:key="index"
center
:timestamp="activity.timestamp"
>
{{ activity.content }}
</el-timeline-item>
</el-timeline>
</el-scrollbar>
<!-- 按钮 -->
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogTableVisible = false">退出</el-button>
</div>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { computed, ref, watch, onMounted } from 'vue';
let dialogTableVisible = ref(false);
const props = defineProps({
fontFamily: {
type: String,
default: 'Segoe UI'
},
fontSize: {
type: Number,
default: 14
},
testColor: {
type: String,
default: '#000000'
},
testBool: {
type: Boolean,
default: true
},
dataSource: {
type: String,
default: '--'
}
});
const activities = [
{
content: '灭火允许',
timestamp: '2018-04-15'
},
{
content: '手动启动',
timestamp: '2018-04-16'
},
{
content: '紧急停止',
timestamp: '2018-04-17'
},
{
content: '手动启动',
timestamp: '2018-04-18'
},
{
content: '灭火允许',
timestamp: '2018-04-15'
},
{
content: '手动启动',
timestamp: '2018-04-16'
},
{
content: '紧急停止',
timestamp: '2018-04-17'
},
{
content: '手动启动',
timestamp: '2018-04-18'
}
];
onMounted(() => {
loadDataSource(props.dataSource);
});
watch(
() => props.dataSource,
(newVal, oldVal) => {
loadDataSource(newVal);
}
);
//
let globalOverviewBool = ref(false);
//
let fireExtinguishingBool = ref(false);
//
let firePoliceBool = ref(false);
function loadDataSource(val: string) {
if (val === 'globalOverview') {
globalOverviewBool.value = true;
fireExtinguishingBool.value = false;
firePoliceBool.value = false;
} else if (val === 'fireExtinguishing') {
globalOverviewBool.value = false;
fireExtinguishingBool.value = true;
firePoliceBool.value = false;
} else if (val === 'firePolice') {
globalOverviewBool.value = false;
fireExtinguishingBool.value = false;
firePoliceBool.value = true;
}
}
let computedSize = computed({
//
get() {
return props.fontSize + 'px';
}, //
set(val) {
console.log('有人修改了fullName', val);
}
});
</script>
<style scoped>
.blue-circle {
width: 12px;
height: 12px;
border-radius: 50%;
background-color: #409eff;
display: inline-block;
margin-left: 5px;
vertical-align: middle;
}
.blueBordered {
background-color: rgb(217, 236, 255);
border: 2px solid rgb(160, 207, 255);
}
.redBordered {
background-color: rgb(253, 226, 226);
border: 2px solid rgb(250, 182, 182);
}
.greenBordered {
background-color: rgb(225, 243, 216);
border: 2px solid rgb(179, 225, 157);
}
:deep(.el-card__body) {
padding: 0;
padding-top: 10px;
padding-left: 10px;
}
:deep(.adTextDetailDialogClass .el-dialog__body) {
max-height: calc(100vh - 150px);
overflow: auto;
border-top: 1px solid #dfdfdf;
border-bottom: 1px solid #dfdfdf;
}
:deep(.adTextDetailDialogClass .el-dialog) {
position: fixed;
height: 20vh !important;
background: #000;
left: 0 !important;
right: 0 !important;
top: 0 !important;
bottom: 0 !important;
margin: auto !important;
}
.el-row .el-col {
margin-bottom: 10px; /* 设置上下间距 */
}
P {
margin: 2px 0px;
padding: 0 15%;
transition: background-color 0.3s ease;
}
P:hover {
background-color: #f0f0f0; /* 悬停时的底色,您可以根据需要调整颜色 */
}
.card {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
/* max-width: 480px; */
color: v-bind('props.testColor');
font-family: v-bind('props.fontFamily');
/* font-family: 'Segoe UI'; */
font-size: v-bind('computedSize');
}
.cardHead {
margin: 0;
padding: 0px;
padding-bottom: 5px;
text-align: center;
}
.cardBody {
width: 100%;
margin: 0 0%;
padding: 0px 0%;
/* padding-bottom: 15px; */
}
</style>

@ -1,93 +0,0 @@
<template>
<el-descriptions class="margin-top" :column="1" size="small" border>
<el-descriptions-item align="center">
<template #label align="center"> 描述 </template>
</el-descriptions-item>
<el-descriptions-item class="tag-info">
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<tickets />
</el-icon>
灯光状态
</div>
</template>
<el-tag size="default" type="success">开启</el-tag>
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<MostlyCloudy />
</el-icon>
湿度
</div>
</template>
80%
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<Sunrise />
</el-icon>
温度
</div>
</template>
36%
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<House />
</el-icon>
节点ID
</div>
</template>
2100210
</el-descriptions-item>
</el-descriptions>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue';
import {
Iphone,
Location,
OfficeBuilding,
Tickets,
User,
House,
MostlyCloudy,
Sunrise
} from '@element-plus/icons-vue';
import type { ComponentSize } from 'element-plus';
const size = ref<ComponentSize>('default');
</script>
<style scoped>
.iconStyle {
marginright: 4px;
}
.el-descriptions {
margin-top: 20px;
}
.cell-item {
display: flex;
align-items: center;
}
.tag-info {
align-items: center;
}
.margin-top {
margin-top: 20px;
}
</style>

@ -1,55 +0,0 @@
<template>
<div style="display: flex; align-items: center">
<el-popover
:width="300"
popper-style="box-shadow: rgb(14 18 22 / 35%) 0px 10px 38px -10px, rgb(14 18 22 / 20%) 0px 10px 20px -15px; padding: 20px;"
>
<template #reference>
<el-switch v-model="value" size="large" active-text="" inactive-text="" />
</template>
<template #default>
<div class="demo-rich-conent" style="display: flex; gap: 2px; flex-direction: column">
<el-switch v-model="value" size="large" disabled />
<el-row :gutter="6">
<el-col :span="12" :xs="24" :sm="12" :md="8" class="elColInfo">
<el-statistic title="绑定ID" value="1100101" />
</el-col>
<el-col :span="12" :xs="24" :sm="12" :md="8" class="elColInfo">
<el-statistic title="状态" :value="null">
<template #suffix>
<el-tag size="default" type="success">开启</el-tag>
</template>
</el-statistic>
</el-col>
<el-col :span="12" :xs="24" :sm="12" :md="8" class="elColInfo">
<el-statistic title="类型" :value="null">
<template #suffix>
<el-tag size="default" type="primary">遥控</el-tag>
</template>
</el-statistic>
</el-col>
</el-row>
</div>
</template>
</el-popover>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const value = ref(true);
</script>
<style scoped>
.el-statistic {
/* 控制文字大小 */
--el-statistic-content-font-size: 16px;
}
.elColInfo {
text-align: center;
}
</style>

@ -1,635 +0,0 @@
<template>
<div class="table-container">
<el-card class="card" shadow="hover" :body-style="{ padding: '10px' }">
<h2 class="cardHead">运行信息</h2>
<div class="table-wrapper" v-loading="arr.length === 0">
<el-table
:data="arr"
:span-method="objectSpanMethods"
style="width: 100%"
class="full-height-table"
@cell-click="handleCellClick"
>
<el-table-column prop="floorName" label="楼层" />
<el-table-column prop="id" label="设备ID" />
<el-table-column prop="name" label="设备名称" />
<el-table-column label="绑定">
<template #default="{ row }">
<el-tag :type="row.isBinding ? 'primary' : 'info'">
{{ row.isBinding ? '绑定' : '待绑' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="设备状态">
<template #default="{ row }">
<el-tag :type="row.eState === 0 ? 'success' : 'warning'">
{{ row.eState === 0 ? '正常' : '故障' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="当前状态">
<template #default="{ row }">
<el-tag v-if="row.currentState === 0" type="success"></el-tag>
<el-tag v-else-if="row.currentState === 1" type="info">停止</el-tag>
<el-tag v-else type="error">报警</el-tag>
</template>
</el-table-column>
<el-table-column label="操作">
<template #default="{ row }">
<el-button type="primary" class="operation-btn" v-if="row.operation">
屏蔽
</el-button>
<el-button type="primary" class="operation-btn" v-else> </el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- <div class="table-wrapper">
<el-table
:data="tableData"
border
:span-method="objectSpanMethod"
class="full-height-table"
style="width: 100%"
@cell-click="handleCellClick"
>
<el-table-column prop="floorName" label="楼层" />
<el-table-column prop="id" label="设备ID" />
<el-table-column prop="name" label="设备名称" />
<el-table-column label="设备状态">
<template #default="{ row }">
<el-tag :type="row.eState === 0 ? 'success' : 'warning'">
{{ row.eState === 0 ? '正常' : '故障' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="当前状态">
<template #default="{ row }">
<el-tag v-if="row.currentState === 0" type="success"></el-tag>
<el-tag v-else-if="row.currentState === 1" type="info">停止</el-tag>
<el-tag v-else type="error">报警</el-tag>
</template>
</el-table-column>
<el-table-column label="操作">
<template #default="{ row }">
<el-button type="primary" class="operation-btn" v-if="row.operation">
屏蔽
</el-button>
<el-button type="primary" class="operation-btn" v-else> </el-button>
</template>
</el-table-column>
</el-table>
</div> -->
</el-card>
</div>
</template>
<script lang="ts" setup>
import type { TableColumnCtx } from 'element-plus';
import { ElMessage } from 'element-plus';
import { computed, onMounted, onUnmounted, ref, watch, reactive } from 'vue';
import { modelApi } from '@/utils/request';
import emitter from '@/utils/emitter';
const loading = ref(false);
//
/// <reference path="../../../global.d.ts" />
interface RecRuntimeData {
double: number;
node: {
name: string;
};
}
interface RecServiceType {
service: {
node: {
runtimes: Record<string, RecRuntimeData>;
};
};
}
interface ExtendedParentWindow extends Window {
Rec?: RecServiceType;
}
interface User {
id: string;
name: string;
amount1: string;
amount2: string;
amount3: number;
}
interface Equipment {
id: string; //ID
address?: string; //
name: string; //
eState: number; // 0 1
currentState: number; // 0 1 2
operation: boolean; // true false
}
interface FloorObj {
floorName: string; //
equipments: Equipment[];
}
// node
interface FloorNode {
roomId: string;
floorName: string;
eqpList: EquipmentNode[];
}
//node
interface EquipmentNode {
id: string; //ID
name: string; //
isBinding: boolean; //
eState: number; // 0 1
currentState: number; // 0 1 2
operation: boolean; // true false
}
function handleCellClick(obj: any) {
console.log('点击:', obj);
emitter.emit('binding-obj-facility-move', obj.id);
}
emitter.on('binding-data-update', () => {
console.log('@@binding-data-update');
dataInit();
});
const props = defineProps({
fontFamily: {
type: String,
default: '黑体'
},
fontSize: {
type: Number,
default: 12
},
testColor: {
type: String,
default: '#ffffff'
},
definitionItemJson: {
type: Object,
default: () => ({})
}
});
console.log('父传子itemjson:', props.definitionItemJson);
//
let computedSize = computed({
//
get() {
return props.fontSize + 'px';
}, //
set(val) {}
});
const arr = ref<any[]>([]);
let targetDataTable: FloorNode[] = [];
let initArrs: any = {};
//
async function dataInit() {
debugger;
initArrs = (window.parent as ExtendedParentWindow).Rec?.service.node.runtimes;
//
arr.value = [];
targetDataTable = [];
loading.value = true;
const response = await modelApi.oneRoomFor_Equipment_get();
if (response.code == 200 && response.data && response.data.length > 0) {
// console.log('', window.parent.Rec.service.node.runtimes);
response.data.forEach((floor: any) => {
let targetData: FloorNode = {
roomId: floor.roomId,
floorName: floor.roomName,
eqpList: []
};
let eqpList: EquipmentNode[] = [];
floor.eqpList.forEach((eqp: any) => {
let currentState = 1;
//
if (initArrs[eqp.nodes[1]].double != 1) currentState = 1;
else if (initArrs[eqp.nodes[2]].double == 1) currentState = 2;
else if (initArrs[eqp.nodes[1]].double == 1) currentState = 0;
let eqpNode: EquipmentNode = {
id: eqp.id,
name: initArrs[eqp.nodes[0]].node.name || '',
eState: initArrs[eqp.nodes[0]].double || 0,
currentState: currentState,
isBinding: eqp.isBinding,
operation: initArrs[eqp.nodes[3]].double == 1
};
eqpList.push(eqpNode);
});
targetData.eqpList = eqpList;
targetDataTable.push(targetData);
});
ElMessage.success('获取接口数据成功');
arr.value = targetDataTable.flatMap((floor) =>
floor.eqpList.map((equipment) => ({
...equipment,
floorName: floor.floorName,
roomId: floor.roomId
}))
);
} else {
ElMessage.error('获取接口数据失败');
}
}
//
const tableDatas = computed(() => {
return targetDataTable.flatMap((floor) =>
floor.eqpList.map((equipment) => ({
...equipment,
floorName: floor.floorName, //
roomId: floor.roomId //
}))
);
});
// onMounted
onMounted(async () => {
await dataInit();
});
onUnmounted(() => {
emitter.off('binding-data-update');
});
//
const floorData: FloorObj[] = [
{
floorName: '安全工器具室',
equipments: [
{
id: 'smokeDetector01',
name: '1号感烟探头',
eState: 0,
currentState: 0,
operation: true
},
{
id: 'smokeDetector02',
name: '2号感烟探头',
eState: 0,
currentState: 0,
operation: true
}
]
},
{
floorName: '蓄电池室',
equipments: [
{
id: 'smokeDetector03',
name: '3号感烟探头',
eState: 1,
currentState: 1,
operation: false
},
{
id: 'smokeDetector04',
name: '4号感烟探头',
eState: 0,
currentState: 0,
operation: true
}
]
},
{
floorName: '220kV保护室',
equipments: [
{
id: 'smokeDetector05',
name: '5号感烟探头',
eState: 0,
currentState: 2,
operation: false
},
{
id: 'smokeDetector06',
name: '6号感烟探头',
eState: 1,
currentState: 1,
operation: true
}
]
},
{
floorName: '380kV配电室',
equipments: [
{
id: 'smokeDetector07',
name: '7号感烟探头',
eState: 0,
currentState: 0,
operation: false
},
{
id: 'smokeDetector08',
name: '8号感烟探头',
eState: 0,
currentState: 2,
operation: true
}
]
},
{
floorName: '35kV高压室',
equipments: [
{
id: 'smokeDetector09',
name: '9号感烟探头',
eState: 1,
currentState: 1,
operation: false
},
{
id: 'smokeDetector10',
name: '10号感烟探头',
eState: 0,
currentState: 0,
operation: true
}
]
},
{
floorName: '2号接地变室',
equipments: [
{
id: 'smokeDetector11',
name: '11号感烟探头',
eState: 0,
currentState: 2,
operation: false
},
{
id: 'smokeDetector12',
name: '12号感烟探头',
eState: 1,
currentState: 1,
operation: true
}
]
},
{
floorName: '110kV电缆室',
equipments: [
{
id: 'smokeDetector13',
name: '13号感烟探头',
eState: 0,
currentState: 0,
operation: false
},
{
id: 'smokeDetector14',
name: '14号感烟探头',
eState: 0,
currentState: 0,
operation: true
}
]
},
{
floorName: '2号站用变室',
equipments: [
{
id: 'smokeDetector15',
name: '15号感烟探头',
eState: 0,
currentState: 0,
operation: false
},
{
id: 'smokeDetector16',
name: '16号感烟探头',
eState: 0,
currentState: 0,
operation: true
}
]
},
{
floorName: '生产综合楼1楼走廊',
equipments: [
{
id: 'smokeDetector17',
name: '17号感烟探头',
eState: 0,
currentState: 0,
operation: false
},
{
id: 'smokeDetector18',
name: '18号感烟探头',
eState: 0,
currentState: 0,
operation: true
},
{
id: '10028',
name: '1号声光报警器',
eState: 0,
currentState: 0,
operation: false
},
{
id: '10029',
name: '2号声光报警器',
eState: 0,
currentState: 0,
operation: true
},
{
id: '10030',
name: '1号手报',
eState: 0,
currentState: 0,
operation: false
},
{
id: '10031',
name: '2号手报',
eState: 0,
currentState: 0,
operation: true
}
]
}
];
interface SpanMethodProps {
row: any;
column: TableColumnCtx<User>;
rowIndex: number;
columnIndex: number;
}
const objectSpanMethods = ({ row, columnIndex }: SpanMethodProps) => {
if (columnIndex === 0) {
//
const floor = targetDataTable.find((f) => f.floorName === row.floorName);
if (floor) {
//
const firstEquipmentIndex = floor.eqpList.findIndex((e) => e.id === row.id);
if (firstEquipmentIndex === 0) {
//
return {
rowspan: floor.eqpList.length,
colspan: 1
};
} else {
//
return {
rowspan: 0,
colspan: 0
};
}
}
}
//
return {
rowspan: 1,
colspan: 1
};
};
const objectSpanMethod = ({ row, columnIndex }: SpanMethodProps) => {
if (columnIndex === 0) {
//
const floor = floorData.find((f) => f.floorName === row.floorName);
if (floor) {
//
const firstEquipmentIndex = floor.equipments.findIndex((e) => e.id === row.id);
if (firstEquipmentIndex === 0) {
//
return {
rowspan: floor.equipments.length,
colspan: 1
};
} else {
//
return {
rowspan: 0,
colspan: 0
};
}
}
}
//
return {
rowspan: 1,
colspan: 1
};
};
//
const tableData = computed(() => {
return floorData.flatMap((floor) =>
floor.equipments.map((equipment) => ({
...equipment,
floorName: floor.floorName, //
//
address: equipment.address || floor.floorName
}))
);
});
</script>
<style scoped>
.table-container {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.card {
flex: 1;
display: flex;
flex-direction: column;
height: 100%;
}
.card :deep(.el-card__body) {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
padding: 10px;
}
.table-wrapper {
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}
.full-height-table {
flex: 1;
height: 100%;
}
.full-height-table :deep(.el-table__body-wrapper) {
flex: 1;
overflow-y: auto;
}
.cardHead {
margin: 0 0 15px 0;
padding: 0;
font-size: 16px;
font-weight: bold;
text-align: center;
color: #ffffff;
flex-shrink: 0;
}
.operation-btn {
width: 60px;
min-width: 50px;
padding: 8px 12px;
height: 30px;
}
/* 控制表头文字大小 */
.full-height-table :deep(.el-table__header th) {
font-size: 13px;
font-weight: bold;
}
/* 控制表格内容文字大小 */
.full-height-table :deep(.el-table__body td) {
font-size: v-bind('computedSize');
color: v-bind('props.testColor');
}
/* 控制标签文字大小 */
.full-height-table :deep(.el-tag) {
font-size: v-bind('computedSize'); /* 标签内的文字可以稍小一些 */
}
/* 控制按钮文字大小 */
.full-height-table :deep(.el-button) {
font-size: v-bind('computedSize');
color: v-bind('props.testColor');
}
</style>

@ -1,200 +0,0 @@
<template>
<div class="compact-table-container">
<el-table ref="singleTableRef" :data="tableData" size="small" style="width: 100%">
<el-table-column type="index" label="序号" />
<el-table-column prop="groupName" label="名称" />
<el-table-column prop="temperatureStr" label="温度" />
<el-table-column prop="humidityStr" label="湿度" />
</el-table>
</div>
<div style="margin-top: 10px" class="compact-button-container">
<el-button @click="getGroupDataList" size="small">获取数据</el-button>
<!-- <el-button @click="setCurrent()" size="small">Clear selection</el-button> -->
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, onUnmounted, onMounted, toRefs, computed } from 'vue';
import { type ResponseMultipleValued, type GroupData } from '@/components/mt-edit/store/types';
import { useDataMapStore } from '@/utils/dataMapStore'; // store
import { storeToRefs } from 'pinia'; // store
interface User {
date: string;
name: string;
address: string;
}
const dataMapStore = useDataMapStore();
const { dataMap } = storeToRefs(dataMapStore);
onMounted(() => {
getGroupDataList();
});
onUnmounted(() => {});
function getvirtualMap(): ResponseMultipleValued {
return {
config: null,
data: [
{
groupName: '组名1001',
temperatureId: 10384,
humidityId: 10385
},
{
groupName: '组名1002',
temperatureId: 11384,
humidityId: 11385
},
{
groupName: '组名1003',
temperatureId: 12384,
humidityId: 12385
},
{
groupName: '组名1004',
temperatureId: 13384,
humidityId: 13385
}
],
headers: null,
request: null,
status: 200,
statusText: 'test'
};
}
interface GroupDatStr {
groupName: string;
temperatureStr: string;
humidityStr: string;
}
const tableData: Array<GroupDatStr> = reactive([]);
async function getGroupDataList() {
// const response: ResponseVue = await axios.get('/api/nrt');
const response: ResponseMultipleValued = getvirtualMap();
response.data.forEach((item) => {
let humidityData = '-';
if (dataMap.value[item.humidityId]) {
humidityData =
dataMap.value[item.humidityId].double + dataMap.value[item.humidityId].node.unit;
}
let temperatureData = '-';
if (dataMap.value[item.temperatureId]) {
temperatureData =
dataMap.value[item.temperatureId].double + dataMap.value[item.temperatureId].node.unit;
}
tableData.push({
groupName: item.groupName,
temperatureStr: humidityData,
humidityStr: temperatureData
});
});
}
const props = defineProps({
fontFamily: {
type: String,
default: '黑体'
},
fontSize: {
type: Number,
default: 12
},
testColor: {
type: String,
default: '#ffffff'
}
});
//
let computedSize = computed({
//
get() {
return props.fontSize + 'px';
}, //
set(val) {
console.log('有人修改了fullName', val);
}
});
</script>
<style scoped>
.compact-button-container {
max-width: 450px;
}
.compact-table-container {
width: 100%;
height: 100%;
overflow-y: auto;
transition: transform 0.3s ease;
}
.compact-table-container .el-table {
font-size: v-bind('computedSize');
}
.compact-table-container .el-table .el-table__cell {
padding: 2px 0;
}
.compact-table-container .el-table th.el-table__cell > .cell {
padding: 0 2px;
}
.compact-table-container .el-table td.el-table__cell > .cell {
padding: 2px 2px;
}
/* 修改表格整体背景色 */
::v-deep .el-table {
background-color: #40beff; /* 浅蓝色背景 */
}
/* 修改表头背景色和文字颜色 */
::v-deep .el-table th.el-table__cell {
/* background-color: #2e349e; 深蓝色表头 */
background-color: #21264e;
color: white; /* 白色文字 */
font-weight: bold;
}
/* 修改表头边框颜色 */
::v-deep .el-table th.el-table__cell {
border: 1px solid #151a3d; /* 深色边框 */
}
/* 修改奇偶行背景色 */
::v-deep .el-table .el-table__body-wrapper tr.el-table__row:nth-child(odd) {
background-color: #40beff; /* 奇数行使用浅蓝色 */
color: v-bind('props.testColor');
font-family: v-bind('props.fontFamily');
}
::v-deep .el-table .el-table__body-wrapper tr.el-table__row:nth-child(even) {
background-color: #2e349e; /* 偶数行使用深蓝色 */
color: v-bind('props.testColor');
font-family: v-bind('props.fontFamily');
}
/* 修改鼠标悬停时的行颜色 */
::v-deep .el-table .el-table__body tr:hover > td {
background-color: rgba(21, 26, 61, 0.7); /* 半透明深蓝色悬停效果,基于#151a3d */
}
/* 修改选中行的颜色 */
::v-deep .el-table .el-table__body tr.current-row > td {
background-color: #151a3d;
color: white;
}
/* 修改单元格边框颜色 */
::v-deep .el-table td.el-table__cell {
border: 1px solid #151a3d; /* 深色边框 */
}
</style>

@ -1,270 +0,0 @@
<template>
<!-- <div class="scale-controls" style="margin-bottom: 10px">
<el-button @click="zoomIn" size="small">放大</el-button>
<el-button @click="zoomOut" size="small">缩小</el-button>
<span style="margin-left: 10px">{{ Math.round(tablesCale * 100) }}%</span>
</div> -->
<div class="compact-table-container-wrapper">
<div class="compact-table-container">
<el-table :data="tableNode" class="compact-table" size="small" height="100%">
<el-table-column type="index" label="序号" />
<el-table-column prop="id" label="ID" />
<el-table-column prop="name" label="名称" />
<el-table-column prop="bType" label="类型" />
<el-table-column prop="dateValue" label="遥值" />
<el-table-column prop="runState" label="运行状态" />
<el-table-column prop="sig" label="区间类型" />
</el-table>
</div>
</div>
<div style="margin-top: 10px" class="compact-button-container">
<el-button @click="getDataList" size="small">获取数据</el-button>
<!-- <el-button @click="setCurrent()" size="small">Clear selection</el-button> -->
</div>
</template>
<script setup lang="ts">
import axios from 'axios';
import { ref, reactive, toRefs, onMounted, watch, computed } from 'vue';
import { type ResponseVue } from '@/components/mt-edit/store/types';
import { useDataMapStore } from '@/utils/dataMapStore';
import { globalStore } from '@/components/mt-edit/store/global';
const emit = defineEmits(['update:modelValue']);
let store = useDataMapStore();
interface NodeDTO {
id: string;
name: string;
bType: string;
dateValue?: string;
runState?: string;
sig?: string;
}
// let fontSize = ref('12px');
function getTypeNameByNum(value: number) {
switch (value) {
case 1:
return '遥信';
case 2:
return '遥测';
case 3:
return '遥控';
case 4:
return '遥调';
default:
return '其他';
}
}
const tableNode: Array<NodeDTO> = reactive([]);
const props = defineProps({
fontFamily: {
type: String,
default: '黑体'
},
fontSize: {
type: Number,
default: 12
},
testColor: {
type: String,
default: '#ffffff'
}
});
//
let computedSize = computed({
//
get() {
return props.fontSize + 'px';
}, //
set(val) {
console.log('有人修改了fullName', val);
}
});
function getRunState(value: number) {
switch (value) {
case 0:
return '不可用/不在线';
case 1:
return '工作状态';
case 2:
return '取代/屏蔽';
default:
return '未知状态';
}
}
function getNodeSigType(value: number) {
switch (value) {
case -2000:
return '未初始化';
case 0:
return '分/复归';
case 1:
return '合/告警';
case 5:
return '联动关';
case -10:
return '预警/低限联动';
case 10:
return '报警/高限联动';
case -20:
return '低限告警';
case 20:
return '高限告警';
default:
return '未知区间状态';
}
}
onMounted(() => {
getDataList();
});
async function getDataList() {
// GET
try {
const response: ResponseVue = await axios.get('/api/nrt');
// response.data
if (response.data) {
store.setDataMap(response.data);
for (const key in response.data) {
const dataItem = response.data[key];
let valStr = ' - ';
let val = dataItem.double;
if (dataItem.bType) {
switch (dataItem.bType) {
case 1: //
case 3: //
case 4: //
if (val > 0) valStr = '开';
else valStr = '关';
break;
case 2: //
valStr = dataItem.double + dataItem.node.unit;
break;
default:
valStr = ' - ';
break;
}
}
if (dataItem.double !== undefined && dataItem.double) {
valStr = dataItem.double + dataItem.node.unit;
}
tableNode.push({
id: dataItem.id.toString(),
name: dataItem.node.name,
bType: getTypeNameByNum(dataItem.bType),
dateValue: valStr,
runState: getRunState(dataItem.runState),
sig: getNodeSigType(dataItem.sig)
});
}
}
} catch (error) {
console.error('请求失败:', error);
}
}
</script>
<style scoped>
.compact-table-container-wrapper {
/* max-width: 1000px; */
/* max-height: 400px; */
width: 100%;
height: 100%;
overflow-y: auto;
}
.compact-table-container {
width: 100%;
height: 100%;
/* max-width: 500px; */
overflow-y: auto;
/* font-size: 20; */
fit: true;
transition: transform 0.3s ease;
}
.compact-table {
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
}
/* 修改表格整体背景色 */
::v-deep .el-table {
background-color: #40beff; /* 浅蓝色背景 */
}
/* 修改表头背景色和文字颜色 */
::v-deep .el-table th.el-table__cell {
/* background-color: #2e349e; 深蓝色表头 */
background-color: #21264e;
color: white; /* 白色文字 */
font-weight: bold;
}
/* 修改表头边框颜色 */
::v-deep .el-table th.el-table__cell {
border: 1px solid #151a3d; /* 深色边框 */
}
/* 修改奇偶行背景色 */
::v-deep .el-table .el-table__body-wrapper tr.el-table__row:nth-child(odd) {
background-color: #40beff; /* 奇数行使用浅蓝色 */
color: v-bind('props.testColor');
font-family: v-bind('props.fontFamily');
}
::v-deep .el-table .el-table__body-wrapper tr.el-table__row:nth-child(even) {
background-color: #2e349e; /* 偶数行使用深蓝色 */
color: v-bind('props.testColor');
font-family: v-bind('props.fontFamily');
}
/* 修改鼠标悬停时的行颜色 */
::v-deep .el-table .el-table__body tr:hover > td {
background-color: rgba(21, 26, 61, 0.7); /* 半透明深蓝色悬停效果,基于#151a3d */
}
/* 修改选中行的颜色 */
::v-deep .el-table .el-table__body tr.current-row > td {
background-color: #151a3d;
color: white;
}
/* 修改单元格边框颜色 */
::v-deep .el-table td.el-table__cell {
border: 1px solid #151a3d; /* 深色边框 */
}
.compact-table-container .el-table {
font-size: v-bind('computedSize');
/* font-size: 12px; */
}
.compact-table-container .el-table .el-table__cell {
padding: 2px 0;
}
.compact-table-container .el-table th.el-table__cell > .cell {
padding: 0 2px;
}
.compact-table-container .el-table td.el-table__cell > .cell {
padding: 2px 2px;
}
</style>
Loading…
Cancel
Save