|
1
|
<script lang="ts" setup>
|
1
|
<script lang="ts" setup>
|
|
2
|
import { nextTick, onMounted, onUnmounted, reactive, ref, unref, computed } from 'vue';
|
2
|
import { nextTick, onMounted, onUnmounted, reactive, ref, unref, computed } from 'vue';
|
|
3
|
- import { List, Card, Tooltip, Space, PaginationProps } from 'ant-design-vue';
|
3
|
+ import { List, Card, Tooltip, Space, PaginationProps, InputNumber } from 'ant-design-vue';
|
|
4
|
import { PageWrapper } from '/@/components/Page';
|
4
|
import { PageWrapper } from '/@/components/Page';
|
|
5
|
import { BasicTable, useTable } from '/@/components/Table';
|
5
|
import { BasicTable, useTable } from '/@/components/Table';
|
|
6
|
import { realTimeDataColumns } from '../../config/detail.config';
|
6
|
import { realTimeDataColumns } from '../../config/detail.config';
|
|
@@ -12,7 +12,7 @@ |
|
@@ -12,7 +12,7 @@ |
|
12
|
import { BasicForm, useForm } from '/@/components/Form';
|
12
|
import { BasicForm, useForm } from '/@/components/Form';
|
|
13
|
import HistoryData from './HistoryData.vue';
|
13
|
import HistoryData from './HistoryData.vue';
|
|
14
|
import { BasicModal, useModal } from '/@/components/Modal';
|
14
|
import { BasicModal, useModal } from '/@/components/Modal';
|
|
15
|
- import { getDeviceAttrs } from '/@/api/device/deviceManager';
|
15
|
+ import { getDeviceAttrs, getDeviceToken } from '/@/api/device/deviceManager';
|
|
16
|
import { DeviceRecord } from '/@/api/device/model/deviceModel';
|
16
|
import { DeviceRecord } from '/@/api/device/model/deviceModel';
|
|
17
|
import { isArray, isNull, isNullOrUnDef, isObject } from '/@/utils/is';
|
17
|
import { isArray, isNull, isNullOrUnDef, isObject } from '/@/utils/is';
|
|
18
|
import { useGlobSetting } from '/@/hooks/setting';
|
18
|
import { useGlobSetting } from '/@/hooks/setting';
|
|
@@ -37,6 +37,8 @@ |
|
@@ -37,6 +37,8 @@ |
|
37
|
} from './ModelOfMatter.config';
|
37
|
} from './ModelOfMatter.config';
|
|
38
|
import { useJsonParse } from '/@/hooks/business/useJsonParse';
|
38
|
import { useJsonParse } from '/@/hooks/business/useJsonParse';
|
|
39
|
import { useI18n } from '/@/hooks/web/useI18n';
|
39
|
import { useI18n } from '/@/hooks/web/useI18n';
|
|
|
|
40
|
+ import { defHttp } from '/@/utils/http/axios';
|
|
|
|
41
|
+
|
|
40
|
|
42
|
|
|
41
|
interface ReceiveMessage {
|
43
|
interface ReceiveMessage {
|
|
42
|
data: {
|
44
|
data: {
|
|
@@ -46,6 +48,41 @@ |
|
@@ -46,6 +48,41 @@ |
|
46
|
|
48
|
|
|
47
|
const { t } = useI18n();
|
49
|
const { t } = useI18n();
|
|
48
|
|
50
|
|
|
|
|
51
|
+ const reportDeviceKeyMap = {
|
|
|
|
52
|
+ GC: '燃气设备',
|
|
|
|
53
|
+ WU: '水表设备',
|
|
|
|
54
|
+ EC: '电表设备',
|
|
|
|
55
|
+ } as const;
|
|
|
|
56
|
+
|
|
|
|
57
|
+ const reportDeviceKeys = Object.keys(reportDeviceKeyMap);
|
|
|
|
58
|
+
|
|
|
|
59
|
+ type ReportDeviceKey = keyof typeof reportDeviceKeyMap;
|
|
|
|
60
|
+
|
|
|
|
61
|
+ const reportFormModel = reactive<Record<ReportDeviceKey, number | undefined>>({
|
|
|
|
62
|
+ GC: undefined,
|
|
|
|
63
|
+ WU: undefined,
|
|
|
|
64
|
+ EC: undefined,
|
|
|
|
65
|
+ });
|
|
|
|
66
|
+
|
|
|
|
67
|
+ const currentReportKey = ref<ReportDeviceKey | ''>('');
|
|
|
|
68
|
+
|
|
|
|
69
|
+ const currentReportLabel = computed(() => {
|
|
|
|
70
|
+ const key = unref(currentReportKey);
|
|
|
|
71
|
+ return key ? reportDeviceKeyMap[key] : '';
|
|
|
|
72
|
+ });
|
|
|
|
73
|
+
|
|
|
|
74
|
+ const currentReportValue = computed<number | undefined>({
|
|
|
|
75
|
+ get() {
|
|
|
|
76
|
+ const key = unref(currentReportKey);
|
|
|
|
77
|
+ return key ? reportFormModel[key] : undefined;
|
|
|
|
78
|
+ },
|
|
|
|
79
|
+ set(value) {
|
|
|
|
80
|
+ const key = unref(currentReportKey);
|
|
|
|
81
|
+ if (!key) return;
|
|
|
|
82
|
+ reportFormModel[key] = value;
|
|
|
|
83
|
+ },
|
|
|
|
84
|
+ });
|
|
|
|
85
|
+
|
|
49
|
const props = defineProps<{
|
86
|
const props = defineProps<{
|
|
50
|
deviceDetail: DeviceRecord;
|
87
|
deviceDetail: DeviceRecord;
|
|
51
|
}>();
|
88
|
}>();
|
|
@@ -197,6 +234,8 @@ |
|
@@ -197,6 +234,8 @@ |
|
197
|
}
|
234
|
}
|
|
198
|
|
235
|
|
|
199
|
const [registerModal, { openModal }] = useModal();
|
236
|
const [registerModal, { openModal }] = useModal();
|
|
|
|
237
|
+ const [registerReportModal, { openModal: openReportModal, closeModal: closeReportModal }] =
|
|
|
|
238
|
+ useModal();
|
|
200
|
|
239
|
|
|
201
|
const mode = ref<EnumTableCardMode>(EnumTableCardMode.CARD);
|
240
|
const mode = ref<EnumTableCardMode>(EnumTableCardMode.CARD);
|
|
202
|
|
241
|
|
|
@@ -291,6 +330,40 @@ |
|
@@ -291,6 +330,40 @@ |
|
291
|
openModal(true);
|
330
|
openModal(true);
|
|
292
|
};
|
331
|
};
|
|
293
|
|
332
|
|
|
|
|
333
|
+ const handleReport = (record: SocketInfoDataSourceItemType) => {
|
|
|
|
334
|
+ const { key } = record;
|
|
|
|
335
|
+ if (!reportDeviceKeys.includes(key)) return;
|
|
|
|
336
|
+ currentReportKey.value = key as ReportDeviceKey;
|
|
|
|
337
|
+ openReportModal(true);
|
|
|
|
338
|
+ };
|
|
|
|
339
|
+
|
|
|
|
340
|
+ const handleReportSave = async () => {
|
|
|
|
341
|
+ const key = unref(currentReportKey);
|
|
|
|
342
|
+ if (!key) return;
|
|
|
|
343
|
+ const token = await getDeviceToken(props.deviceDetail.tbDeviceId);
|
|
|
|
344
|
+ console.log('token.credentialsId', token.credentialsId);
|
|
|
|
345
|
+ console.log('handleReportSave', { key, value: reportFormModel[key] });
|
|
|
|
346
|
+ // https://iot.hzzlyun.com/api/v1/HPlEWlrVPNlAbZ6WQpn2/telemetry
|
|
|
|
347
|
+ // 入参
|
|
|
|
348
|
+ const data = { [key]: reportFormModel[key] };
|
|
|
|
349
|
+ const credentialsId = token.credentialsId;
|
|
|
|
350
|
+ // 写一个接口请求,固定链接,不依赖token https://iot.hzzlyun.com/api/v1/${credentialsId}/telemetry
|
|
|
|
351
|
+ await defHttp.post(
|
|
|
|
352
|
+ {
|
|
|
|
353
|
+ url: `https://iot.hzzlyun.com/api/v1/${credentialsId}/telemetry`,
|
|
|
|
354
|
+ data,
|
|
|
|
355
|
+ },
|
|
|
|
356
|
+ {
|
|
|
|
357
|
+ joinPrefix: false,
|
|
|
|
358
|
+ apiUrl: '',
|
|
|
|
359
|
+ withToken: false,
|
|
|
|
360
|
+ }
|
|
|
|
361
|
+ );
|
|
|
|
362
|
+
|
|
|
|
363
|
+ createMessage.success('保存成功');
|
|
|
|
364
|
+ closeReportModal();
|
|
|
|
365
|
+ };
|
|
|
|
366
|
+
|
|
294
|
const getIsModbusDevice = computed(
|
367
|
const getIsModbusDevice = computed(
|
|
295
|
() =>
|
368
|
() =>
|
|
296
|
props.deviceDetail.transportType === TransportTypeEnum.TCP &&
|
369
|
props.deviceDetail.transportType === TransportTypeEnum.TCP &&
|
|
@@ -307,21 +380,21 @@ |
|
@@ -307,21 +380,21 @@ |
|
307
|
open();
|
380
|
open();
|
|
308
|
});
|
381
|
});
|
|
309
|
|
382
|
|
|
310
|
- const formatValue = (item: SocketInfoDataSourceItemType) => {
|
383
|
+ const formatValue = (item: SocketInfoDataSourceItemType): string => {
|
|
311
|
if (isNullOrUnDef(item) || isNullOrUnDef(item.value)) return '--';
|
384
|
if (isNullOrUnDef(item) || isNullOrUnDef(item.value)) return '--';
|
|
312
|
|
385
|
|
|
313
|
if (unref(getIsModbusDevice) && item.type === DataTypeEnum.BOOL) {
|
386
|
if (unref(getIsModbusDevice) && item.type === DataTypeEnum.BOOL) {
|
|
314
|
const _result = Reflect.get(item.enum || {}, item.value as string);
|
387
|
const _result = Reflect.get(item.enum || {}, item.value as string);
|
|
315
|
- return isNullOrUnDef(_result) ? item.value : _result;
|
388
|
+ return isNullOrUnDef(_result) ? String(item.value) : String(_result);
|
|
316
|
}
|
389
|
}
|
|
317
|
|
390
|
|
|
318
|
switch (item.type) {
|
391
|
switch (item.type) {
|
|
319
|
case DataTypeEnum.BOOL:
|
392
|
case DataTypeEnum.BOOL:
|
|
320
|
- return !!Number(item.value) ? item.boolOpen! : item.boolClose!;
|
393
|
+ return !!Number(item.value) ? (item.boolOpen ?? '--') : (item.boolClose ?? '--');
|
|
321
|
case DataTypeEnum.ENUM:
|
394
|
case DataTypeEnum.ENUM:
|
|
322
|
- return item.enum?.[item.value as string];
|
395
|
+ return item.enum?.[item.value as string] ?? '--';
|
|
323
|
default:
|
396
|
default:
|
|
324
|
- return item.value || '--';
|
397
|
+ return String(item.value ?? '--');
|
|
325
|
}
|
398
|
}
|
|
326
|
};
|
399
|
};
|
|
327
|
|
400
|
|
|
@@ -429,6 +502,22 @@ |
|
@@ -429,6 +502,22 @@ |
|
429
|
@click="handleShowDetail(item)"
|
502
|
@click="handleShowDetail(item)"
|
|
430
|
/>
|
503
|
/>
|
|
431
|
</Tooltip>
|
504
|
</Tooltip>
|
|
|
|
505
|
+ <!-- 上报按钮 显示判断 -->
|
|
|
|
506
|
+ <!-- 燃气设备 GC-->
|
|
|
|
507
|
+ <!-- 水表设备 WU-->
|
|
|
|
508
|
+ <!-- 电表设备 EC-->
|
|
|
|
509
|
+ <Tooltip :title="t('business.reportText')"
|
|
|
|
510
|
+ v-if="reportDeviceKeys.includes(item.key)"
|
|
|
|
511
|
+ >
|
|
|
|
512
|
+ <SvgIcon
|
|
|
|
513
|
+ name="shuiwen"
|
|
|
|
514
|
+ prefix="iconfont"
|
|
|
|
515
|
+ class="cursor-pointer text-lg text-blue-500"
|
|
|
|
516
|
+ @click="handleReport(item)"
|
|
|
|
517
|
+ />
|
|
|
|
518
|
+ </Tooltip>
|
|
|
|
519
|
+
|
|
|
|
520
|
+
|
|
432
|
</Space>
|
521
|
</Space>
|
|
433
|
</template>
|
522
|
</template>
|
|
434
|
<section class="min-h-16 flex flex-col justify-between">
|
523
|
<section class="min-h-16 flex flex-col justify-between">
|
|
@@ -513,6 +602,21 @@ |
|
@@ -513,6 +602,21 @@ |
|
513
|
>
|
602
|
>
|
|
514
|
<HistoryData :deviceDetail="props.deviceDetail" :attr="socketInfo.attr" />
|
603
|
<HistoryData :deviceDetail="props.deviceDetail" :attr="socketInfo.attr" />
|
|
515
|
</BasicModal>
|
604
|
</BasicModal>
|
|
|
|
605
|
+ <BasicModal
|
|
|
|
606
|
+ @register="registerReportModal"
|
|
|
|
607
|
+ :title="`${t('business.reportText')}`"
|
|
|
|
608
|
+ width="40%"
|
|
|
|
609
|
+ :minHeight="0"
|
|
|
|
610
|
+ :bodyStyle="{ padding: '12px 16px' }"
|
|
|
|
611
|
+ destroy-on-close
|
|
|
|
612
|
+ okText="提交"
|
|
|
|
613
|
+ @ok="handleReportSave"
|
|
|
|
614
|
+ >
|
|
|
|
615
|
+ <div class="p-1 flex items-center gap-2">
|
|
|
|
616
|
+ <div class="w-20 text-right whitespace-nowrap">{{ currentReportLabel }}</div>
|
|
|
|
617
|
+ <InputNumber v-model:value="currentReportValue" class="flex-1 w-full" size="small" />
|
|
|
|
618
|
+ </div>
|
|
|
|
619
|
+ </BasicModal>
|
|
516
|
<ObjectModelCommandDeliveryModal
|
620
|
<ObjectModelCommandDeliveryModal
|
|
517
|
@register="register"
|
621
|
@register="register"
|
|
518
|
:deviceId="deviceDetail.tbDeviceId"
|
622
|
:deviceId="deviceDetail.tbDeviceId"
|