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 169 {
170 170 title: '告警时间',
171 171 dataIndex: 'createdTime',
172   - width: 120,
  172 + width: 180,
173 173 },
174 174 {
175 175 title: '告警设备',
176 176 dataIndex: 'deviceName',
177   - width: 100,
  177 + width: 120,
178 178 },
179 179 {
180 180 title: '告警场景',
... ... @@ -184,14 +184,20 @@ export const alarmColumns: BasicColumn[] = [
184 184 {
185 185 title: '告警级别',
186 186 dataIndex: 'severity',
187   - width: 160,
  187 + width: 90,
188 188 format: (text) => alarmLevel(text),
189 189 },
190 190 {
  191 + title: '告警详情',
  192 + dataIndex: 'details',
  193 + slots: { customRender: 'details' },
  194 + width: 160,
  195 + },
  196 + {
191 197 title: '状态',
192 198 dataIndex: 'status',
193 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 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 274 export const childDeviceSchemas: FormSchema[] = [
... ...
... ... @@ -54,10 +54,6 @@
54 54 await resetFields();
55 55 await setFieldsValue({
56 56 ...data,
57   - details: JSON.stringify(data?.details?.data).slice(
58   - 1,
59   - JSON.stringify(data?.details?.data).length - 1
60   - ),
61 57 severity: alarmLevel(data.severity),
62 58 status: statusType(data.status),
63 59 });
... ...
... ... @@ -12,17 +12,31 @@
12 12 ]"
13 13 />
14 14 </template>
  15 + <template #details="{ record }">
  16 + <a-button type="link" class="ml-2" @click="handleViewAlarmDetails(record)">
  17 + 查看告警详情
  18 + </a-button>
  19 + </template>
15 20 </BasicTable>
16 21 <AlarmDetailModal @register="registerDetailModal" @success="handleSuccess" />
17 22 </div>
18 23 </template>
19 24 <script lang="ts">
20   - import { defineComponent } from 'vue';
  25 + import { defineComponent, h, nextTick } from 'vue';
21 26 import { BasicTable, useTable, TableAction } from '/@/components/Table';
22 27 import { alarmColumns, alarmSearchSchemas } from '../../config/detail.config';
23 28 import { getDeviceAlarm } from '/@/api/device/deviceManager';
24 29 import AlarmDetailModal from '../modal/AlarmDetailModal.vue';
25 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 40 export default defineComponent({
27 41 name: 'DeviceManagement',
28 42 components: {
... ... @@ -66,11 +80,81 @@
66 80 const handleSuccess = () => {
67 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 152 return {
70 153 registerTable,
71 154 registerDetailModal,
72 155 handleDetail,
73 156 handleSuccess,
  157 + handleViewAlarmDetails,
74 158 };
75 159 },
76 160 });
... ...
... ... @@ -164,26 +164,26 @@ export const genActionData = (actionData) => {
164 164 };
165 165
166 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 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 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 189 export const scheduleOptions = [
... ...