|
@@ -1,42 +1,7 @@
|
|
|
<!-- eslint-disable vue/multi-word-component-names -->
|
|
|
<template>
|
|
|
- <!-- Header部分 -->
|
|
|
- <div v-if="headerConfig.show" class="w-100% flex content__header">
|
|
|
- <!-- 选择下拉框,自动填充剩余空间,这种实现是因为 Select 不支持 suffix -->
|
|
|
- <Dropdown
|
|
|
- v-if="headerConfig.showSelector"
|
|
|
- class="flex-grow-1 content__header_left"
|
|
|
- :trigger="['click']"
|
|
|
- :bordered="false"
|
|
|
- @open-change="headerVisible = $event"
|
|
|
- >
|
|
|
- <div class="w-100% flex flex-items-center" @click.prevent>
|
|
|
- <SwapOutlined class="w-30px" />
|
|
|
- <div class="flex-grow-1">
|
|
|
- {{ selectedDeviceLabel }}
|
|
|
- </div>
|
|
|
- <CaretUpOutlined class="w-30px" v-if="headerVisible" />
|
|
|
- <CaretDownOutlined class="w-30px" v-else />
|
|
|
- </div>
|
|
|
- <template #overlay>
|
|
|
- <Menu :selected-keys="[selectedDeviceID]" @click="headerSelectHandler">
|
|
|
- <MenuItem v-for="item in options" :key="item.value" :title="item.label">
|
|
|
- {{ item.label }}
|
|
|
- </MenuItem>
|
|
|
- </Menu>
|
|
|
- </template>
|
|
|
- </Dropdown>
|
|
|
- <template v-if="headerConfig.showSlot">
|
|
|
- <div class="flex flex-items-center flex-grow-1 content__header_right">
|
|
|
- <SwapOutlined class="w-30px" />
|
|
|
- <div class="flex-grow-1">
|
|
|
- {{ selectedDeviceSlot }}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </div>
|
|
|
<!-- 主体内容部分 -->
|
|
|
- <div class="content" :class="{ content_without_header: !headerConfig.show }">
|
|
|
+ <div class="content">
|
|
|
<!-- 背景 -->
|
|
|
<img v-if="background.show && background.type === 'image'" class="content__background" :src="background.link" />
|
|
|
<video
|
|
@@ -75,30 +40,36 @@
|
|
|
<CustomList class="content__module" :type="config.type" :list-config="config.items" />
|
|
|
</template>
|
|
|
</template>
|
|
|
+ <!-- 画廊部分 -->
|
|
|
<template v-if="config.key === 'gallery'">
|
|
|
<CustomGallery class="content__module" :type="config.type" :gallery-config="config.items" />
|
|
|
</template>
|
|
|
+ <!-- 复杂列表部分 -->
|
|
|
+ <template v-if="config.key === 'gallery_list'">
|
|
|
+ <GalleryList class="content__module" :type="config.type" :list-config="config.items" :gallery-config="config.galleryItems" />
|
|
|
+ </template>
|
|
|
+ <!-- 复杂列表部分 -->
|
|
|
<template v-if="config.key === 'complex_list'">
|
|
|
- <ComplexList class="content__module" :type="config.type" :list-config="config.items" :gallery-config="config.galleryItems" />
|
|
|
+ <ComplexList class="content__module" :type="config.type" :list-config="config.items" />
|
|
|
</template>
|
|
|
<!-- 表格部分,这部分通常是占一整个模块的 -->
|
|
|
<template v-if="config.key === 'table'">
|
|
|
<CommonTable
|
|
|
v-if="config.type === 'A'"
|
|
|
:columns="config.columns"
|
|
|
- :data="tableData"
|
|
|
+ :data="config.data"
|
|
|
class="content__module text-center flex-grow overflow-auto"
|
|
|
/>
|
|
|
<CustomTable
|
|
|
v-else
|
|
|
:type="config.type"
|
|
|
:columns="config.columns"
|
|
|
- :data="tableData"
|
|
|
+ :data="config.data"
|
|
|
class="content__module text-center flex-grow overflow-auto"
|
|
|
/>
|
|
|
</template>
|
|
|
<template v-if="config.key === 'blast_delta'">
|
|
|
- <BlastDelta class="content__module" :pos-monitor="blastDeltaData" :canvas-size="{ width: 250, height: 137 }" />
|
|
|
+ <BlastDelta class="content__module" :pos-monitor="config.config.mock" :canvas-size="{ width: 250, height: 137 }" />
|
|
|
</template>
|
|
|
<template v-if="config.key === 'fire_control'">
|
|
|
<FIreControl class="content__module" />
|
|
@@ -110,7 +81,7 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
<script lang="ts" setup>
|
|
|
- import { computed, onMounted, ref } from 'vue';
|
|
|
+ import { computed } from 'vue';
|
|
|
import {
|
|
|
Config,
|
|
|
// ModuleDataBoard,
|
|
@@ -119,39 +90,45 @@
|
|
|
// ModuleDataPreset,
|
|
|
// ModuleDataTable,
|
|
|
} from '../../../deviceManager/configurationTable/types';
|
|
|
- import { useInitDevices } from '../hooks/useInit';
|
|
|
- import { MenuItem, Menu, Dropdown } from 'ant-design-vue';
|
|
|
- import { SwapOutlined, CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons-vue';
|
|
|
- import MiniBoard from './MiniBoard.vue';
|
|
|
- import TimelineList from './TimelineList.vue';
|
|
|
- import CustomList from './CustomList.vue';
|
|
|
- import CustomGallery from './CustomGallery.vue';
|
|
|
- import ComplexList from './ComplexList.vue';
|
|
|
- import CustomTable from './CustomTable.vue';
|
|
|
- import { getFormattedText, getRawProp } from '../../../deviceManager/configurationTable/adapters';
|
|
|
- import CustomChart from './CustomChart.vue';
|
|
|
+ import MiniBoard from './detail/MiniBoard.vue';
|
|
|
+ import TimelineList from './detail/TimelineList.vue';
|
|
|
+ import CustomList from './detail/CustomList.vue';
|
|
|
+ import CustomGallery from './detail/CustomGallery.vue';
|
|
|
+ import ComplexList from './detail/ComplexList.vue';
|
|
|
+ import GalleryList from './detail/GalleryList.vue';
|
|
|
+ import CustomTable from './detail/CustomTable.vue';
|
|
|
+ import CustomChart from './detail/CustomChart.vue';
|
|
|
import { get, clone } from 'lodash-es';
|
|
|
+ import { getFormattedText } from '../../../deviceManager/configurationTable/adapters';
|
|
|
import CommonTable from '../../billboard/components/CommonTable.vue';
|
|
|
import BlastDelta from '../../../monitorManager/deviceMonitor/components/device/modal/blastDelta.vue';
|
|
|
- import FIreWarn from './FIreWarn.vue';
|
|
|
- import FIreControl from './FIreControl.vue';
|
|
|
- import { posMonitorData } from '../configurable.data';
|
|
|
+ import FIreWarn from './preset/FIreWarn.vue';
|
|
|
+ import FIreControl from './preset/FIreControl.vue';
|
|
|
|
|
|
const props = defineProps<{
|
|
|
- deviceType: Config['deviceType'];
|
|
|
+ data: any;
|
|
|
moduleData: Config['moduleData'];
|
|
|
- showStyle: Config['showStyle'];
|
|
|
}>();
|
|
|
|
|
|
- const { header: headerConfig, background, layout, mock } = props.moduleData;
|
|
|
+ const { background, layout } = props.moduleData;
|
|
|
+
|
|
|
+ // 额外的 header 相关的变量
|
|
|
+
|
|
|
+ function getData(raw, readFrom) {
|
|
|
+ if (readFrom) {
|
|
|
+ return get(raw, readFrom);
|
|
|
+ }
|
|
|
+ return raw;
|
|
|
+ }
|
|
|
|
|
|
/** 根据配置里的layout将配置格式化为带 key 的具体配置,例如:[{ key: 'list', value: any, ...ModuleDataList }] */
|
|
|
const layoutConfig = computed(() => {
|
|
|
- const refData = selectedDevice.value;
|
|
|
+ const refData = props.data;
|
|
|
const board = clone(props.moduleData.board);
|
|
|
const list = clone(props.moduleData.list);
|
|
|
const gallery = clone(props.moduleData.gallery);
|
|
|
const complex_list = clone(props.moduleData.complex_list);
|
|
|
+ const gallery_list = clone(props.moduleData.gallery_list);
|
|
|
const chart = clone(props.moduleData.chart);
|
|
|
const table = clone(props.moduleData.table);
|
|
|
const preset = clone(props.moduleData.preset);
|
|
@@ -161,7 +138,7 @@
|
|
|
case 'board': {
|
|
|
const cfg = board.shift();
|
|
|
if (!cfg) break;
|
|
|
- const data = mock || cfg.readFrom ? get(refData, cfg.readFrom) : refData;
|
|
|
+ const data = getData(refData, cfg.readFrom);
|
|
|
|
|
|
arr.push({
|
|
|
...cfg,
|
|
@@ -170,7 +147,7 @@
|
|
|
return {
|
|
|
...i,
|
|
|
label: getFormattedText(data, i.label),
|
|
|
- value: getFormattedText(data, i.prop),
|
|
|
+ value: getFormattedText(data, i.value),
|
|
|
};
|
|
|
}),
|
|
|
});
|
|
@@ -179,7 +156,8 @@
|
|
|
case 'list': {
|
|
|
const cfg = list.shift();
|
|
|
if (!cfg) break;
|
|
|
- const data = mock || cfg.readFrom ? get(refData, cfg.readFrom) : refData;
|
|
|
+ const data = getData(refData, cfg.readFrom);
|
|
|
+
|
|
|
arr.push({
|
|
|
...cfg,
|
|
|
key,
|
|
@@ -187,7 +165,7 @@
|
|
|
return {
|
|
|
...i,
|
|
|
label: getFormattedText(data, i.label),
|
|
|
- value: getFormattedText(data, i.prop),
|
|
|
+ value: getFormattedText(data, i.value),
|
|
|
};
|
|
|
}),
|
|
|
});
|
|
@@ -196,7 +174,7 @@
|
|
|
case 'gallery': {
|
|
|
const cfg = gallery.shift();
|
|
|
if (!cfg) break;
|
|
|
- const data = mock || cfg.readFrom ? get(refData, cfg.readFrom) : refData;
|
|
|
+ const data = getData(refData, cfg.readFrom);
|
|
|
|
|
|
arr.push({
|
|
|
...cfg,
|
|
@@ -205,7 +183,7 @@
|
|
|
return {
|
|
|
...i,
|
|
|
label: getFormattedText(data, i.label),
|
|
|
- value: getFormattedText(data, i.prop),
|
|
|
+ value: getFormattedText(data, i.value),
|
|
|
};
|
|
|
}),
|
|
|
});
|
|
@@ -214,7 +192,30 @@
|
|
|
case 'complex_list': {
|
|
|
const cfg = complex_list.shift();
|
|
|
if (!cfg) break;
|
|
|
- const data = mock || cfg.readFrom ? get(refData, cfg.readFrom) : refData;
|
|
|
+ const data = getData(refData, cfg.readFrom);
|
|
|
+
|
|
|
+ arr.push({
|
|
|
+ ...cfg,
|
|
|
+ key,
|
|
|
+ items: cfg.items.map((i) => {
|
|
|
+ return {
|
|
|
+ title: getFormattedText(data, i.title),
|
|
|
+ contents: i.contents.map((e) => {
|
|
|
+ return {
|
|
|
+ ...e,
|
|
|
+ label: getFormattedText(data, e.label),
|
|
|
+ value: getFormattedText(data, e.value),
|
|
|
+ };
|
|
|
+ }),
|
|
|
+ };
|
|
|
+ }),
|
|
|
+ });
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case 'gallery_list': {
|
|
|
+ const cfg = gallery_list.shift();
|
|
|
+ if (!cfg) break;
|
|
|
+ const data = getData(refData, cfg.readFrom);
|
|
|
|
|
|
arr.push({
|
|
|
...cfg,
|
|
@@ -223,14 +224,14 @@
|
|
|
return {
|
|
|
...i,
|
|
|
label: getFormattedText(data, i.label),
|
|
|
- value: getFormattedText(data, i.prop),
|
|
|
+ value: getFormattedText(data, i.value),
|
|
|
};
|
|
|
}),
|
|
|
galleryItems: cfg.galleryItems.map((i) => {
|
|
|
return {
|
|
|
...i,
|
|
|
label: getFormattedText(data, i.label),
|
|
|
- value: getFormattedText(data, i.prop),
|
|
|
+ value: getFormattedText(data, i.value),
|
|
|
};
|
|
|
}),
|
|
|
});
|
|
@@ -239,7 +240,7 @@
|
|
|
case 'chart': {
|
|
|
const cfg = chart.shift();
|
|
|
if (!cfg) break;
|
|
|
- const data = mock || cfg.readFrom ? get(refData, cfg.readFrom) : refData;
|
|
|
+ const data = getData(refData, cfg.readFrom);
|
|
|
|
|
|
arr.push({
|
|
|
key,
|
|
@@ -251,17 +252,12 @@
|
|
|
case 'table': {
|
|
|
const cfg = table.shift();
|
|
|
if (!cfg) break;
|
|
|
- const data = mock || cfg.readFrom ? get(refData, cfg.readFrom) : refData;
|
|
|
+ const data = getData(refData, cfg.readFrom);
|
|
|
|
|
|
arr.push({
|
|
|
...cfg,
|
|
|
key,
|
|
|
- columns: (cfg.columns || []).map((e) => {
|
|
|
- return {
|
|
|
- name: e.label,
|
|
|
- prop: getRawProp(e.prop),
|
|
|
- };
|
|
|
- }),
|
|
|
+ columns: cfg.columns,
|
|
|
data: get(data, cfg.readFrom, []),
|
|
|
});
|
|
|
break;
|
|
@@ -269,7 +265,7 @@
|
|
|
default: {
|
|
|
const cfg = preset.shift();
|
|
|
if (!cfg) break;
|
|
|
- const data = mock || cfg.readFrom ? get(refData, cfg.readFrom) : refData;
|
|
|
+ const data = getData(refData, cfg.readFrom);
|
|
|
|
|
|
arr.push({
|
|
|
key,
|
|
@@ -282,110 +278,6 @@
|
|
|
return arr;
|
|
|
}, []);
|
|
|
});
|
|
|
-
|
|
|
- // 额外的 header 相关的变量
|
|
|
- const headerVisible = ref(false);
|
|
|
- function headerSelectHandler({ key }) {
|
|
|
- selectedDeviceID.value = key;
|
|
|
- }
|
|
|
-
|
|
|
- // 额外的告示牌相关的变量
|
|
|
- // const boardConfig = computed(() => {
|
|
|
- // const data = selectedDevice.value;
|
|
|
- // return (board || []).map((b) => {
|
|
|
- // return {
|
|
|
- // ...b.items,
|
|
|
- // value: getFormattedText(data, b.prop, b.formatter),
|
|
|
- // };
|
|
|
- // });
|
|
|
- // });
|
|
|
-
|
|
|
- // 额外的时间线列表相关的变量
|
|
|
- // const listConfig = computed(() => {
|
|
|
- // const data = selectedDevice.value;
|
|
|
- // return (list || []).map((b) => {
|
|
|
- // return {
|
|
|
- // ...b,
|
|
|
- // value: getFormattedText(data, b.prop, b.formatter),
|
|
|
- // };
|
|
|
- // });
|
|
|
- // });
|
|
|
- // const listType = computed(() => {
|
|
|
- // return list[0]?.type || 'A';
|
|
|
- // });
|
|
|
-
|
|
|
- // const chartConfig = computed(() => {
|
|
|
- // return chart[0];
|
|
|
- // });
|
|
|
- // const chartData = computed(() => {
|
|
|
- // const data = selectedDevice.value;
|
|
|
- // return get(data, chart[0]?.readFrom, []);
|
|
|
- // });
|
|
|
-
|
|
|
- // const tableConfig = computed(() => {
|
|
|
- // return {
|
|
|
- // columns: (table[0]?.columns || []).map((e) => {
|
|
|
- // return {
|
|
|
- // name: e.label,
|
|
|
- // prop: e.prop,
|
|
|
- // };
|
|
|
- // }),
|
|
|
- // };
|
|
|
- // });
|
|
|
- const tableData = computed(() => {
|
|
|
- // const data = selectedDevice.value;
|
|
|
- return [
|
|
|
- {
|
|
|
- index: '1',
|
|
|
- time: '2024/07/22 07:00',
|
|
|
- warn: '未知',
|
|
|
- cate: 'xxx综采工作面',
|
|
|
- temp: '26',
|
|
|
- wspd: '2',
|
|
|
- spst: 'ON',
|
|
|
- },
|
|
|
- {
|
|
|
- index: '2',
|
|
|
- time: '2024/07/22 08:00',
|
|
|
- warn: '未知',
|
|
|
- cate: 'xxx综采工作面',
|
|
|
- temp: '26',
|
|
|
- wspd: '2',
|
|
|
- spst: 'ON',
|
|
|
- },
|
|
|
- {
|
|
|
- index: '3',
|
|
|
- time: '2024/07/22 09:00',
|
|
|
- warn: '未知',
|
|
|
- cate: 'xxx综采工作面',
|
|
|
- temp: '26',
|
|
|
- wspd: '2',
|
|
|
- spst: 'ON',
|
|
|
- },
|
|
|
- {
|
|
|
- index: '4',
|
|
|
- time: '2024/07/22 10:00',
|
|
|
- warn: '未知',
|
|
|
- cate: 'xxx综采工作面',
|
|
|
- temp: '26',
|
|
|
- wspd: '2',
|
|
|
- spst: 'ON',
|
|
|
- },
|
|
|
- ];
|
|
|
- // return get(data, table[0]?.readFrom, []);
|
|
|
- });
|
|
|
-
|
|
|
- const blastDeltaData = ref();
|
|
|
-
|
|
|
- const { selectedDeviceID, selectedDevice, selectedDeviceSlot, selectedDeviceLabel, options, fetchDevices } = useInitDevices(
|
|
|
- props.deviceType,
|
|
|
- headerConfig
|
|
|
- );
|
|
|
-
|
|
|
- onMounted(() => {
|
|
|
- blastDeltaData.value = posMonitorData;
|
|
|
- fetchDevices();
|
|
|
- });
|
|
|
</script>
|
|
|
<style lang="less" scoped>
|
|
|
@import '@/design/vent/color.less';
|
|
@@ -415,9 +307,6 @@
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
}
|
|
|
- .content_without_header {
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
.content__background {
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
@@ -431,12 +320,12 @@
|
|
|
margin-top: 5px;
|
|
|
margin-bottom: 5px;
|
|
|
}
|
|
|
- .content__module:first-of-type {
|
|
|
- margin-top: 0;
|
|
|
- }
|
|
|
- .content__module:last-of-type {
|
|
|
- margin-bottom: 0;
|
|
|
- }
|
|
|
+ // .content__module:first-of-type {
|
|
|
+ // margin-top: 0;
|
|
|
+ // }
|
|
|
+ // .content__module:last-of-type {
|
|
|
+ // margin-bottom: 0;
|
|
|
+ // }
|
|
|
::v-deep .zxm-select:not(.zxm-select-customize-input) .zxm-select-selector {
|
|
|
/* background-color: transparent; */
|
|
|
color: #fff;
|