Commit 9590a599d07a4d9a3f76ecf5201903c8082a81f8

Authored by xp.Huang
2 parents 51a11031 7b98391a

Merge branch 'ft' into 'main_dev'

feat: 设备告警,新增告警详情显示

See merge request yunteng/thingskit-front!823
@@ -169,12 +169,12 @@ export const alarmColumns: BasicColumn[] = [ @@ -169,12 +169,12 @@ export const alarmColumns: BasicColumn[] = [
169 { 169 {
170 title: '告警时间', 170 title: '告警时间',
171 dataIndex: 'createdTime', 171 dataIndex: 'createdTime',
172 - width: 120, 172 + width: 180,
173 }, 173 },
174 { 174 {
175 title: '告警设备', 175 title: '告警设备',
176 dataIndex: 'deviceName', 176 dataIndex: 'deviceName',
177 - width: 100, 177 + width: 120,
178 }, 178 },
179 { 179 {
180 title: '告警场景', 180 title: '告警场景',
@@ -184,14 +184,20 @@ export const alarmColumns: BasicColumn[] = [ @@ -184,14 +184,20 @@ export const alarmColumns: BasicColumn[] = [
184 { 184 {
185 title: '告警级别', 185 title: '告警级别',
186 dataIndex: 'severity', 186 dataIndex: 'severity',
187 - width: 160, 187 + width: 90,
188 format: (text) => alarmLevel(text), 188 format: (text) => alarmLevel(text),
189 }, 189 },
190 { 190 {
  191 + title: '告警详情',
  192 + dataIndex: 'details',
  193 + slots: { customRender: 'details' },
  194 + width: 160,
  195 + },
  196 + {
191 title: '状态', 197 title: '状态',
192 dataIndex: 'status', 198 dataIndex: 'status',
193 format: (text) => statusType(text), 199 format: (text) => statusType(text),
194 - width: 160, 200 + width: 100,
195 }, 201 },
196 ]; 202 ];
197 203
@@ -263,14 +269,6 @@ export const alarmSchemasForm: FormSchema[] = [ @@ -263,14 +269,6 @@ export const alarmSchemasForm: FormSchema[] = [
263 disabled: true, 269 disabled: true,
264 }, 270 },
265 }, 271 },
266 - {  
267 - field: 'details',  
268 - label: '详情',  
269 - component: 'InputTextArea',  
270 - componentProps: {  
271 - maxLength: 255,  
272 - },  
273 - },  
274 ]; 272 ];
275 // 子设备 273 // 子设备
276 export const childDeviceSchemas: FormSchema[] = [ 274 export const childDeviceSchemas: FormSchema[] = [
@@ -54,10 +54,6 @@ @@ -54,10 +54,6 @@
54 await resetFields(); 54 await resetFields();
55 await setFieldsValue({ 55 await setFieldsValue({
56 ...data, 56 ...data,
57 - details: JSON.stringify(data?.details?.data).slice(  
58 - 1,  
59 - JSON.stringify(data?.details?.data).length - 1  
60 - ),  
61 severity: alarmLevel(data.severity), 57 severity: alarmLevel(data.severity),
62 status: statusType(data.status), 58 status: statusType(data.status),
63 }); 59 });
@@ -12,17 +12,31 @@ @@ -12,17 +12,31 @@
12 ]" 12 ]"
13 /> 13 />
14 </template> 14 </template>
  15 + <template #details="{ record }">
  16 + <a-button type="link" class="ml-2" @click="handleViewAlarmDetails(record)">
  17 + 查看告警详情
  18 + </a-button>
  19 + </template>
15 </BasicTable> 20 </BasicTable>
16 <AlarmDetailModal @register="registerDetailModal" @success="handleSuccess" /> 21 <AlarmDetailModal @register="registerDetailModal" @success="handleSuccess" />
17 </div> 22 </div>
18 </template> 23 </template>
19 <script lang="ts"> 24 <script lang="ts">
20 - import { defineComponent } from 'vue'; 25 + import { defineComponent, h, nextTick } from 'vue';
21 import { BasicTable, useTable, TableAction } from '/@/components/Table'; 26 import { BasicTable, useTable, TableAction } from '/@/components/Table';
22 import { alarmColumns, alarmSearchSchemas } from '../../config/detail.config'; 27 import { alarmColumns, alarmSearchSchemas } from '../../config/detail.config';
23 import { getDeviceAlarm } from '/@/api/device/deviceManager'; 28 import { getDeviceAlarm } from '/@/api/device/deviceManager';
24 import AlarmDetailModal from '../modal/AlarmDetailModal.vue'; 29 import AlarmDetailModal from '../modal/AlarmDetailModal.vue';
25 import { useModal } from '/@/components/Modal'; 30 import { useModal } from '/@/components/Modal';
  31 + import { Modal } from 'ant-design-vue';
  32 + import { JsonPreview } from '/@/components/CodeEditor';
  33 + import { getDeviceDetail } from '/@/api/device/deviceManager';
  34 + import { getAttribute } from '/@/api/ruleengine/ruleengineApi';
  35 + import {
  36 + operationNumber_OR_TIME,
  37 + operationString,
  38 + operationBoolean,
  39 + } from '/@/views/rule/linkedge/config/formatData';
26 export default defineComponent({ 40 export default defineComponent({
27 name: 'DeviceManagement', 41 name: 'DeviceManagement',
28 components: { 42 components: {
@@ -66,11 +80,81 @@ @@ -66,11 +80,81 @@
66 const handleSuccess = () => { 80 const handleSuccess = () => {
67 reload(); 81 reload();
68 }; 82 };
  83 + const handleViewAlarmDetails = async (record: Recordable) => {
  84 + await nextTick();
  85 + const { details } = record;
  86 + const deviceIdKeys = Object.keys(details);
  87 + const detailObject = deviceIdKeys.map((key) => ({ label: key, value: details[key] }));
  88 + const dataFormat = await handleAlarmDetailFormat(deviceIdKeys);
  89 + const dataFormats = detailObject.reduce((acc: any, curr: any) => {
  90 + dataFormat.forEach((item) => {
  91 + if (item.tbDeviceId === curr.label) {
  92 + const findName = item.attribute.find(
  93 + (item) => item.identifier === curr.value.key
  94 + )?.name;
  95 + const findLogin = [
  96 + ...operationNumber_OR_TIME,
  97 + ...operationString,
  98 + ...operationBoolean,
  99 + ].find((item) => item.value === curr.value.logic)?.symbol;
  100 + const value = {
  101 + ['触发属性']: findName,
  102 + ['触发条件']: `${findLogin}${curr.value.logicValue}`,
  103 + ['触发值']: curr.value.realValue,
  104 + };
  105 + const data = {
  106 + [item.name]: value,
  107 + };
  108 + acc.push(data);
  109 + }
  110 + });
  111 + return [...acc];
  112 + }, []);
  113 + const objectFormat = dataFormats.reduce((acc: any, curr: any) => {
  114 + return {
  115 + ...acc,
  116 + ...curr,
  117 + };
  118 + }, {});
  119 + Modal.info({
  120 + title: '告警详情',
  121 + width: 600,
  122 + centered: true,
  123 + maskClosable: true,
  124 + content: h(JsonPreview, { data: JSON.parse(JSON.stringify(objectFormat)) }),
  125 + });
  126 + };
  127 + const handleAlarmDetailFormat = async (keys: string[]) => {
  128 + const temp: any = [];
  129 + for (let item of keys) {
  130 + if (item === 'key' || item === 'data') return; //旧数据则终止
  131 + const deviceDetailRes = await getDeviceDetail(item);
  132 + const { deviceProfileId } = deviceDetailRes;
  133 + if (!deviceProfileId) return;
  134 + const attributeRes = await getAttribute(deviceProfileId);
  135 + const dataFormat: any = handleDataFormat(deviceDetailRes, attributeRes);
  136 + temp.push(dataFormat);
  137 + }
  138 + return temp;
  139 + };
  140 + const handleDataFormat = (deviceDetail: any, attributes: any) => {
  141 + const { name, tbDeviceId } = deviceDetail;
  142 + const attribute = attributes.map((item) => ({
  143 + identifier: item.identifier,
  144 + name: item.name,
  145 + }));
  146 + return {
  147 + name,
  148 + tbDeviceId,
  149 + attribute,
  150 + };
  151 + };
69 return { 152 return {
70 registerTable, 153 registerTable,
71 registerDetailModal, 154 registerDetailModal,
72 handleDetail, 155 handleDetail,
73 handleSuccess, 156 handleSuccess,
  157 + handleViewAlarmDetails,
74 }; 158 };
75 }, 159 },
76 }); 160 });
@@ -164,26 +164,26 @@ export const genActionData = (actionData) => { @@ -164,26 +164,26 @@ export const genActionData = (actionData) => {
164 }; 164 };
165 165
166 export const operationNumber_OR_TIME = [ 166 export const operationNumber_OR_TIME = [
167 - { label: '等于', value: Number_Operation.EQUAL },  
168 - { label: '不等于', value: Number_Operation.NOT_EQUAL },  
169 - { label: '小于', value: Number_Operation.LESS },  
170 - { label: '小于等于', value: Number_Operation.LESS_OR_EQUAL },  
171 - { label: '大于', value: Number_Operation.GREATER },  
172 - { label: '大于等于', value: Number_Operation.GREATER_OR_EQUAL }, 167 + { label: '等于', value: Number_Operation.EQUAL, symbol: '=' },
  168 + { label: '不等于', value: Number_Operation.NOT_EQUAL, symbol: '!=' },
  169 + { label: '小于', value: Number_Operation.LESS, symbol: '<' },
  170 + { label: '小于等于', value: Number_Operation.LESS_OR_EQUAL, symbol: '<=' },
  171 + { label: '大于', value: Number_Operation.GREATER, symbol: '>' },
  172 + { label: '大于等于', value: Number_Operation.GREATER_OR_EQUAL, symbol: '>=' },
173 ]; 173 ];
174 174
175 export const operationString = [ 175 export const operationString = [
176 - { label: '等于', value: String_Operation.EQUAL },  
177 - { label: '不等于', value: String_Operation.NOT_EQUAL },  
178 - { label: '开始于', value: String_Operation.BEGAN_IN },  
179 - { label: '结束于', value: String_Operation.END_IN },  
180 - { label: '包含', value: String_Operation.INCLUDE },  
181 - { label: '不包含', value: String_Operation.NOT_INCLUDE }, 176 + { label: '等于', value: String_Operation.EQUAL, symbol: '=' },
  177 + { label: '不等于', value: String_Operation.NOT_EQUAL, symbol: '!=' },
  178 + { label: '开始于', value: String_Operation.BEGAN_IN, symbol: '开始于' },
  179 + { label: '结束于', value: String_Operation.END_IN, symbol: '结束于' },
  180 + { label: '包含', value: String_Operation.INCLUDE, symbol: '包含' },
  181 + { label: '不包含', value: String_Operation.NOT_INCLUDE, symbol: '不包含' },
182 ]; 182 ];
183 183
184 export const operationBoolean = [ 184 export const operationBoolean = [
185 - { label: '等于', value: Boolean_Operation.EQUAL },  
186 - { label: '不等于', value: Boolean_Operation.NOT_EQUAL }, 185 + { label: '等于', value: Boolean_Operation.EQUAL, symbol: '=' },
  186 + { label: '不等于', value: Boolean_Operation.NOT_EQUAL, symbol: '!=' },
187 ]; 187 ];
188 188
189 export const scheduleOptions = [ 189 export const scheduleOptions = [