Commit b0714d21c87829f08c2f4cb6c44f67cc17b76055

Authored by 史婷婷
1 parent 7be7525e

feat: 设备-详情-三个设备类型(燃气、水表、电表)增加上报功能

@@ -6,12 +6,12 @@ VITE_GLOB_PUBLIC_PATH = / @@ -6,12 +6,12 @@ VITE_GLOB_PUBLIC_PATH = /
6 6
7 # Cross-domain proxy, you can configure multiple 7 # Cross-domain proxy, you can configure multiple
8 # Please note that no line breaks 8 # Please note that no line breaks
9 - 9 +# https://iot.hzzlyun.com 线上生产地址
10 # 本地 10 # 本地
11 -VITE_PROXY = [["/api","http://10.9.0.205:8080/api"],["/thingskit-scada","http://localhost:5173/thingskit-scada"],["/large-designer", "http://localhost:5555/large-designer/"]] 11 +VITE_PROXY = [["/api","https://iot.hzzlyun.com/api"],["/thingskit-scada","http://localhost:5173/thingskit-scada"],["/large-designer", "http://localhost:5555/large-designer/"]]
12 12
13 # 实时数据的ws地址 13 # 实时数据的ws地址
14 -VITE_GLOB_WEB_SOCKET = ws://10.9.0.205:8080/api/ws/plugins/telemetry?token= 14 +VITE_GLOB_WEB_SOCKET = wss://iot.hzzlyun.com/api/ws/plugins/telemetry?token=
15 15
16 # Delete console 16 # Delete console
17 VITE_GLOB_DROP_CONSOLE = true 17 VITE_GLOB_DROP_CONSOLE = true
@@ -28,5 +28,6 @@ export default { @@ -28,5 +28,6 @@ export default {
28 historyTrendText: 'History trend', 28 historyTrendText: 'History trend',
29 commandDeliveryText: 'Command delivery', 29 commandDeliveryText: 'Command delivery',
30 serviceText: 'Service', 30 serviceText: 'Service',
  31 + reportText: 'Report',
31 dateRangeText: 'Date range', 32 dateRangeText: 'Date range',
32 }; 33 };
@@ -30,6 +30,7 @@ export default { @@ -30,6 +30,7 @@ export default {
30 historyTrendText: '历史趋势', 30 historyTrendText: '历史趋势',
31 commandDeliveryText: '命令下发', 31 commandDeliveryText: '命令下发',
32 serviceText: '服务', 32 serviceText: '服务',
  33 + reportText: '上报',
33 dateRangeText: '时间范围', 34 dateRangeText: '时间范围',
34 directorName: '负责人', 35 directorName: '负责人',
35 }; 36 };
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"